Gaudiy Tech Blog

Gaudiyの技術、開発組織、カルチャーについてお伝えするブログです

ゼロトラストをベースにセキュリティを考えてみた

f:id:gaudiy:20220311101244p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている土居(@taro_engineer)です。

最近はバックエンドからインフラ周りを担当していますが、今回は「ゼロトラスト」の考えをベースにしたセキュリティの構築をテーマに書いてみたいと思います。

ゼロトラストの定義やセキュリティに関する説明は難しい部分もあるので、正直このテーマで書くべきか僕自身も悩みました(笑)。

ただ、今回導入を検討するにあたり、ネットを調べてもほとんど実例が見当たらなかったので、僕らが調べたことや考えたことがどなたかのご参考になれば嬉しいです。

1. Gaudiyのマイクロサービスアーキテクチャ

本題に入る前に、Gaudiyのプロダクトについて簡単に説明します。

Gaudiyでは、IPコンテンツを有するエンタメ企業に対して、ブロックチェーンを活用したファンコミュニティサービスを開発・提供しています。

このコミュニティアプリは、IPごとにカスタマイズ可能な形で複数の機能を提供しているため、バックエンドにはマイクロサービスを採用しています。

f:id:gaudiy:20220310234806p:plain

全体のアーキテクチャ構成

たとえば、決済サービス、動画配信、ゲームアプリなど、クライアントの既存サービスとコミュニティアプリを連携させています。これらの依存関係を排して、拡張性をもちながら機能提供したいという背景から、マイクロサービスを採用しました。

また、スピード感をもってマイクロサービスを構築するために、コストの高いk8sではなくCloudRunを採用して、規模の拡大に伴って移行できるような体制にしています。

2. セキュリティを「今」考えるべき理由

Gaudiyが取り扱っているのは、多くのファンを有するエンタメIPのコミュニティであり、クライアントはSony Musicさんや集英社さんなど、いわゆるエンタープライズ企業です。

これまでも拡張性の高いソフトウェア設計に取り組んできましたが、今後、さらなる事業拡大や大型IPのコミュニティ開設が控えている中で、セキュリティの観点においても早めに注力する必要があると考えていました。

この検討にあたって意識したのは、早期にセキュリティの仕組みを検討することと、プロダクト特性に合わせた選択を行うことです。

たとえば、プロダクトでなにかしらの脆弱性が見つかった場合を想定します。ここでもし、セキュリティ対策のために根本的な改修が必要となると、数週間・数ヶ月かかる可能性があります。

これは既にあるアプリケーションをよりスケーラブルにしたり、ステートレスな作りにすることが難しいのと同じ原理で、早い段階からセキュリティも設計していく必要があります。

また、社内のコンプライアンスという観点でも、人が増えることによって脆弱性のリスクは上がっていきます。あるサーバーを通じて情報を悪用する人が現れてしまう可能性は、チームが大きくなればなるほど高くなります。

こうした理由から、今後の事業拡大を見越した先行投資として、”今” から近い将来を考慮したセキュリティの仕組みを構築していくことが大事だと考えました。

その設計における思想として、今回採用することにしたのが「ゼロトラスト」です。

ゼロトラストは、最近ちょっとしたバズワードになっていると思うのですが、そもそもゼロトラストとはなんなのか。Gaudiyではなぜゼロトラストの概念を採用して、どのような取り組みをしているのかについて、お伝えしたいと思います。

3. ゼロトラストとGaudiyでの採用背景

3-1. ゼロトラストとは?

そもそも、ゼロトラストとはなにか。さまざまな解釈があり、明確に定義することが難しいワードですが、個人的にはメルペイ @kokukumaさんの「ひとつの何かに依存して、すべてを許可するのをやめること」という説明が一番しっくりきています。

(こちらの記事はアーカイブ動画を含めてとても参考になりました。)

engineering.mercari.com

またGoogleの記事では、以下のように言及されています。

ゼロトラストアプローチの中核となるのは、複雑で相互接続されたシステムの単一コンポーネントに対する盲目的な信頼は、重大なセキュリティ リスクをまねく可能性があるという考えです。

詳しくは記事内に書かれていますが、安全かどうかを確かめる仕組みを複数用意して、継続的に検証をすることが、ゼロトラストのコアな部分なのだと理解しています。

Gaudiyでは、このゼロトラストの考え方、特にBeyondProdをもとにGCPを基盤とするセキュリティの構築を行っています。

3-2. BeyondCorpとBeyondProd

次に前提知識として、Googleが提唱するゼロトラストモデル 「BeyondCorp」と「BeyondProd」についてもご紹介したいと思います。

これらは、どちらもいわゆる”ゼロトラスト”なのですが、アプローチや視点が違います。

BeyondCorpは、エンドユーザーがアプリケーションにアクセスするときの考え方・フレームワークです。具体例としては、カフェや自宅などの社外から、社内データに安全にアクセスするなどが挙げられます。

一方のBeyondProdは、マイクロサービス間・アーキテクチャ設計の考え方・フレームワークです。具体例としては、サービスメッシュやBinaly Authorizationが挙げられます。

3-3. Gaudiyとゼロトラスト

ではなぜ、Gaudiyではゼロトラストの思想を取り入れたのか。

先述のとおり、Gaudiyは事業も組織も急速に拡大するフェーズにあり、マイクロサービスアーキテクチャを採用しています。

マイクロサービスは、数十・数百のサーバーに分かれるので、その分アクセスできる入り口が複数あります。境界型のセキュリティの場合、境界を超えた先のさまざまなサーバーにアクセスできる可能性があるため、マイクロサービスとしては完全にセキュアとは言えません。

そこで今回は、「ひとつの何かに依存して、すべてを許可するのをやめる」というゼロトラストの思想の中でも、マイクロサービス間・アーキテクチャ設計の考え方である Beyond Prodをもとに、まずはアーキテクチャのゼロトラストを考えました。

一方、ゼロトラストは技術的に難しいですし工数もかなりかかるので、「マイクロサービスだからゼロトラストにするべき」という考えは“ベスト“であって、安直に“マスト“と捉えるべきではないかなとも思っています。

スタートアップの規模感や優先度によっては、良い選択肢ではない場合の方が多いかもしれません。ですが、Gaudiy では事業拡大を見据えて

  • メガベンチャークラスになると、誰でも簡単にアクセスできないような考慮が必要になってくる(社内のコンプライアンスの観点)
  • 工数がまだ低い段階で投資した方が、のちの開発コスト削減につながる

と考えたことから、今のフェーズでゼロトラストの思想を取り入れることにしました。

最後に、ほんの一部かつごく一般的な事例になりますが、具体的に取り組んでいる対策を紹介できればと思います。

4. Gaudiyにおけるゼロトラストの適用

私たちはバックエンドサービスの実行環境に、主にCloud Runを使用しています。このCloud Run自体がゼロトラストととても親和性が高く、フルマネージドで簡単に導入できる部分があります。

そのひとつがサービス間の認証です。呼び出される側のサービスが、どのサービスからであればアクセスできるかの権限を指定することができます。

これはBeyondProdを参考にすると、セキュリティ原則のひとつである、サービス間の相互信頼を確認できる機能だと認識することができます。

このサービス間の認証は、Cloud Runを利用している人にとっては基本的なことだとは思います。ですが、BeyondProdの視点があるだけで、クラウドネイティブアーキテクチャを設計するときにセキュリティ面の対策を意識的に考えられるし、サービス間のあるべき関係性もより深く考えられるかなと思います。

加えて、Cloud Runの権限設定周りもIaCを活用して管理しています。単にクラウド設定の自動化により、デリバリーの認知負荷を低減するという意図もありますが、サービス間のコンテキスト依存の関係もコードとして理解できる点が、チーム開発や新規のアーキテクチャを構成する際に有用だなと感じています。

5. さいごに

完璧なゼロトラストを実現するには、まだまだ足りない部分があり、正直かなり難しい分野だと思います。

Gaudiyでは今後の事業成長やチーム拡大を見据えてゼロトラストを選択しましたが、事業のフェーズや規模によっては、ゼロトラストの適用は逆にコストになり、大きなリターンは生まれないとも感じました。

プロダクトの機能をつくっていくフェーズにおいては、どうしてもセキュリティに取り組む優先度が下がってしまう傾向もあると思いますが、もし事業拡大・人数の増加が見込まれるのであれば、早期に取り組んでおいて損はないと感じました。あとから適用するのは、やはりそれなりのコストがかかってきます。

またクラウドを利用する場合、クラウドが提供する各種サービスの様々な設定をきちんと理解・把握して、ビジネスに反映させていくことが改めて大切だと実感しています。

Gaudiyでもまだ試行錯誤しながら取り組んでいる段階なので、ゼロトラストやマイクロサービスアーキテクチャの設計に興味や知見がある人がいたら、ぜひお話ししたいです!

meety.net

Gaudiyの技術選定とその思想は、以下の記事をご参考ください!

techblog.gaudiy.com

非エンジニアがテックブログを編集する技術

f:id:gaudiy:20220302213923p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでコーポレートサクセス(人事広報)を担当している山本(@hanahanayaman)です。

Gaudiy Tech Blogは、2021年7月に開設し、これまでに累計27本の記事を公開してきました。このブログが、28本目になります。

Gaudiyでは広報担当(わたし)が執筆者に伴走する形でテックブログを運営していますが、他社人事の方のお話をお伺いする限り、わりと珍しい運営体制なのでは? と感じるようになりました。

そこで今回は、非エンジニアでもテックブログの編集できるよ!!ということをお伝えしたく、普段意識していることを書いてみます。

テックブログを始めたいけどどう関わればよいかわからない採用・広報担当の方や、テックブログの質を高めたいエンジニアの方などに、ご参考になれば嬉しいです。

1. 約8ヶ月で27本。テックブログの運営で感じたこと

テックブログやるべき?効果あるの?論をたまにTwitterで見かけますが、Gaudiyで運営していて思うのは、「継続すれば、確実に効果はある」ということです。

f:id:hanahanayaman:20220223182731p:plain

テックブログのPV推移

上図は、テックブログを開始した2021年7月から現在に至るまでのPVの変化です。最初3ヶ月の総PV数が 10,421 だったのに対し、直近3ヶ月の総PV数は 48,351 と、5倍近い数値になっています。

更新ペースは週1本を目安にコツコツと続けていますが、Gaudiyの場合は、大きなバズ記事がたまにポンと出る感じではなく、1本1本の記事がコンスタントに読まれるようになってきた感覚があります。

そして、立ち上げのきっかけである「エンジニア採用」への効果も着実に出ています。「テックブログなどの発信が盛んで、おもしろそうな会社だと思いました」という動機で副業を始めてくださった方がいたり、スカウト返信率も確実に向上しています。

また、日々の学びを体系化し、アウトプットする習慣がついたり、社内のナレッジ共有にもなったりするので、テックブログは良いことづくめです。

2. 技術を知らなくても編集できるのか?

とはいえ、テックブログは "継続" と "クオリティの担保" が最大の難所だと思っています。

わたしは前職で「SELECK」というWebメディアの編集者をしていたので、社内編集者としての立場から、テックブログの運営をサポートしてきました。(継続の工夫については、ALL STAR SAAS FUNDさんに取材いただいた以下の記事が詳しいです。)

blog.allstarsaas.com

ですが、「編集」に対する知見はあっても、技術的なことはわかりません。エンジニア採用も初めての経験です。

技術を知らないのに、編集できるの? と思われる方もいると思います(わたしも不安でした)が、実際に8ヶ月継続してきた中で断言できるのは、技術的なことに詳しくなくても、編集はできます。

その上で、わたしが伝えたい大事な観点が3つあります。

  1. 想定読者の目線を得るための前提知識をインプットすること
  2. 「わかりやすく・読みやすい」ための編集をすること
  3. 「コンテンツの価値は書き手にある」という意識を持つこと

では、具体的にどうやっているのかをご紹介していきます。

3. 想定読者の目線を得るため、前提知識をインプットする

まず大前提として、読んでほしい人にきちんと届けるためには、徹底した「読者目線」が必要です。なぜなら、届けたい相手によって、伝えるべき情報の内容や量が異なるからです。

(ほかの観点は、以前こちらのnoteでまとめたのでよければご参考ください。)

note.com

そこで記事を書き始める前に、必ずテーマと「誰に届けたいのか?」をエンジニアと擦り合わせています。そして、この時に設定した「想定読者」の目線をもって編集するということがとても重要です。

そのために実践しているのは、想定読者が普段触れているであろう情報をインプットすること。具体的には、以下のようなことを編集に入る前の事前準備として行っています。

  • この記事テーマを書く上でエンジニアが参考にした記事やスライドなどを読む
  • 想定読者をバイネームで挙げてもらって、その人のTwitterを見にいく(どんな記事をシェアしてるのか、どんなことに関心があるのかを知る)
  • 記事テーマのキーワードをTwitterやGoogleで検索して関連記事を読む

こういうアクションを取れば、細かい技術的な話はわからなくても、どんな文脈でそのテーマが語られることが多いのか? を理解することができます。

その上で、類似テーマの他社記事との違いを明確にできるように、差別化できそうなポイントをエンジニアにも確認します。

4. 「わかりやすく、読みやすく」するための編集術

一通りのインプットを終えたら、編集に入ります。実を言うと、前提知識のインプットさえできてしまえば、あとは通常のブログ編集と同じです。

わたしが心掛けているのは「わかりやすく、読みやすい」です。大きく分けると「構造」「文章」「見ため」を編集しています。

4-1. 構造の編集

ひとつめは「構造」の編集。以下のような点を意識しています。

  • 小見出しだけでスッと理解できる流れにする
  • メインテーマの論旨から逸れる内容はカットする
  • 段落の前後関係を意識する
  • 段落ごとの情報量を調整する

よくありがちなのは、技術の話からいきなり始まって背景が抜けてしまったり、伝えたいことを盛り込みすぎて逆にメインの論旨がぼやけてしまったりすることです。

たとえば、先日の「GraphQLにおけるエラーハンドリングの実践」という記事では、以下が元の構成でした。

f:id:gaudiy:20220302230449p:plain

元の構成もシンプルでいい感じです。これを、以下のような構成に編集しました。(「はじめに」の段落の内容は、本文に入る前の導入部に入れました。)

f:id:gaudiy:20220302225610p:plain

改めてみると同じワード使いすぎて見にくい説ありますw

小見出しの付け方はあまり良い例ではないのですが(汗)、編集者目線としては、「具体的な技術の話をする前に、まずはエラーハンドリングやGraphQLの特性など前提情報を揃えること」「Gaudiyでの課題を明示した上で技術の話に展開すること」といった構成を意識しました。

4-2. 文章の編集

ふたつめは「文章」の編集。なるべく "シンプルであること" を念頭におき、以下のような点を意識しています。

  • 長い一文は分割する
  • 不要な修飾語をどんどん取り除く
  • 想定読者にとってわかりやすい言葉に変換する
  • 丁寧すぎる言い回しをシンプルな表現にする
  • 同じ用語の繰り返しは代名詞に置き換える

文章の書き方については、すでに巷にたくさんノウハウがあるので詳細は割愛します。個人的なおすすめは、ベイジさんの以下ブログです。例文つきでめちゃくちゃわかりやすいです。

baigie.me

4-3. 見ための編集

最後の仕上げとして、"読みやすく" するために大事なのが「見ため」の編集。ここでは「情報の強弱・リズム・視認性」の観点で、以下のような点を意識しています。

  • 句読点を入れる(リズム)
  • 伝えたい / 強調したい箇所は「」や太字にする(強弱)
  • 4行以上続いたら改行する(視認性)
  • 適度にひらがなを使う(視認性)
  • 箇条書きや引用などの記法を適切に入れる(視認性)
  • テキストだけでなく図や参考記事などを入れる(視認性)

たとえば、以下のような文章があります。

品質を上げること?開発速度を上げること?

ここについては、幾度も議論されているし、全く同意している。

では、それ以外にないだろうか?

チーム間、役職間のコミュニケーションにおいてもテストは有効だと考える。

元の文章も、問いかけから引き込まれるようなGOODな文になっていますが、以下のように編集しました。(引用元:テスト文化はなぜ作れないのか?

「品質を上げるか、開発速度を上げるか」

ここについては、以下のスライドにもあるように幾度も議論されているし、「質とスピードはトレードオフでない」という点には完全に同意しています。

(中略)

ですが、テストの意義として、実はもうひとつの視点があると考えています。それは「チーム間、職種間のコミュニケーションツール」としてのテストです。

太字や「」を使って特に強調したい文章を目立たせたり、あえて「実はもうひとつの視点があると考えています。」と一呼吸置いてから「それは〜〜です。」と伝えることで、主張を際立たせたりしています。

ほんの一例ですが、読みやすく・わかりやすい記事にするための編集を加えています。

5. 編集者はあくまで黒子。コンテンツの価値は書き手にある

さいごに、社内のメンバーにも伝えたいことを書きます。それは「コンテンツの価値は書き手が生み出したものである」ということです。

先日、顧問編集者のWORDS代表・竹村さんのツイートがわかりみ深すぎたので、引用させていただきます。

Gaudiyのエンジニアメンバーは優しい人が多いので、なかには「編集してくれたから記事が伸びた」と思っている人も少なからずいる気がします。(推測なので思い違いだったらごめんなさい。笑)

でも、これは違います。コンテンツを生み出すのは書き手自身です。テックブログを書く前に、そもそもメンバーが日々考え、学び、新しいことに挑戦しているからこそ価値あるコンテンツが生まれる。書く時点でもう、コンテンツの潜在価値は決まっています。

編集者の役割は、100ある潜在価値を、きちんと100の価値として世の中に届けること

もし編集者が「よいコンテンツにしよう」と意気込んでいたら、それは少しはりきり過ぎかもしれません。笑 「本来の価値をしっかり伝えよう」それだけで十分です。

逆に「自分のブログなのに編集されるのなんかヤダな」と感じているエンジニアの方がいたら、ちょっと見方を変えてみてください。本当はもっと価値があるのに、それが世の中に伝わっていないのは、もったいないと思いませんか?

そういうお互いの理解が、よい記事を生み出すと思います。

6. おわりに

今回は「テックブログを編集する技術」をテーマにお届けしました。

完全にタイトル先行の思いつきで書き始めましたが、ふり返ってみて思ったのは、テックブログもそうではない記事も、編集者としてやっていることは大差ないということ。(エンジニアみたいに「技術」ってカッコよく言いたかっただけ。笑)

今回、大切なこととして3点挙げましたが、これらは通常のブログ編集でも同じです。

  1. 想定読者の目線を得るための前提知識をインプットすること
  2. 「わかりやすく・読みやすい」ための編集をすること
  3. 「コンテンツの価値は書き手にある」という意識を持つこと

編集に携わる人には「書き手へのリスペクト」を、執筆する人には「編集のもつ力」を感じていただけたらな、という想いを込めたので、それが伝わっていれば嬉しいです。

---

Gaudiyではブログも採用も全員で取り組んでいます。もっと知りたくなったエンジニアの方は、ぜひCulture Deckもご覧ください!!

www.notion.so

エンジニア採用、広報まわり、気になる方いたらMeetyで話しましょう〜!(わたしの仲間も募集中。)

meety.net

テスト文化はなぜ作れないのか?

f:id:hanahanayaman:20220225125959p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでフロントエンドエンジニアをしているkodai(@r34b26)です。

Gaudiyでは、以前のtech blogでお伝えしたように、ATDDやフロントエンドのテストに取り組んできました。

techblog.gaudiy.com

ですが、正直にいうと、Cucumberを使ったフロントATDDは運用がうまく回っていません。

なぜ失敗したか? を振り返ってみると、「設計を変える(=テストを書く)こと」だけに注力してしまい、「コミュニケーションの構造を変えなかったこと」が原因だということに思い当たりました。

そこで今回は、テスト文化を醸成するためのコミュニケーション設計をテーマに、ブログを書いてみたいと思います。

テスト文化を組織に定着させたいけどうまくいっていないチームの方々に、ご参考になったら嬉しいです。

1. テストを書く意義とは

「品質を上げるか、開発速度を上げるか」

ここについては、以下のスライドにもあるように幾度も議論されているし、「質とスピードはトレードオフでない」という点には完全に同意しています。

質とスピード(2020秋100分拡大版) / Quality and Speed 2020 Autumn Edition - Speaker Deck

つまり、テストを書くことで、プロダクト品質も開発スピードも高めることができる。これは多くのエンジニアが理解していることだと思います。

ですが、テストの意義として、実はもうひとつの視点があると考えています。それは「チーム間、職種間のコミュニケーションツール」としてのテストです。

テストが「ドメイン理解者の定義する要件を満たし、その実行結果が正常であると担保されている状態で、実装者以外のすべてのステークホルダーが理解できる」という理想形であるならば、それを Single Source of Truth として意思決定することができます。

これは特に、チームの人数が増えてきて、コミュニケーション課題が生じてきた際に効果を発揮します。

なぜなら、通常はチームを分割すると、認知負荷が増え、組織全体の効率が下がってしまう傾向にありますが、テストをコミュニケーションの「インターフェース」として活用することで、必要最小限の回数での意思疎通が可能になるからです。

つまり、組織が最大効率でアウトプットを出すには、テストを介したコミュニケーションが重要だと言えます。

2. テスト文化はなぜ定着しないのか?

プロダクトの質も開発スピードも高め、コミュニケーションツールにもなる。こんな良いことだらけなのに、なぜテスト文化は定着しないのでしょうか。

これを「Conwayの法則」をもとに考えてみたいと思います。

"組織の設計するシステムは、その組織のコミュニケーション構造をそのまま反映した設計になる"(Melvin Conway)

テストに置き換えて考えると、

(すべて or 特定の) テストを書かないというソフトウェア設計になっている組織は、
(すべて or 特定の)コミュニケーションを必要としない/していないという構造を反映している

ということになります。

たとえば、スタートアップの創業期や新規事業が発足してまもない頃であれば、プロダクトの意思決定からデザイン、実装まで一人ないしごく少数で行うため、阿吽の呼吸が通用する場合も多く、コミュニケーションをそこまで必要としません。

開発者としての効率と質の向上が大事なフェーズであるため、そこにテストを採用すべきかは、その人の実装力以上の問題にはならないと思います。

ですが、順調に拡大してきた時には問題が生じてきます。

人数が増え、PdM/フロントエンドエンジニア/バックエンドエンジニア/デザイナーなどの専門性の分岐が進むと、コミュニケーション構造の変化が追いつかなくなります。

このコミュニケーション構造とチーム編成の変化速度のGAPが大きくなるほどに、明確にその状態がアプリケーションに反映されてしまうのです。

具体的には、

  • UIデザイナーの成果物からズレた実装が多発する
  • UXデザイナーが想定したものと違う挙動になる
  • バックエンドのAPIの形式がフロントエンドから扱いたい形と異なる
  • PMの定めたプロダクトビジョンと乖離したプロダクトになる

などが発生し、手戻りが頻発する。のちに大規模な再設計をしないといけなくなるといった負債が積もっていく。

このような状態になってから問題に気づき、TDD、ATDDのような手法の有用性に辿り着いたときには、あまりに多くの人の動き方を変えなければなりません。

”テスト文化を作る”ことに焦っている。その状態が、もはや失敗です。

3. テスト文化を醸成するための組織設計

つまり言いたいのは、表出した問題に対して、”テスト文化の醸成”という手法だけに捉われるから、テスト文化が定着しないのではないか、ということ。

冒頭でも触れたように、Gaudiyでも設計を変える(=テストを書く)ことだけに注力してしまった結果、フロントATDDの運用がうまく回りませんでした

何が起きてしまったかというと、

  • “受け入れ基準”をドメイン理解者と一緒につくることや、相互フィードバックをして調整することを怠ってしまい、テスト可能な受け入れ条件をつくることができなかった。その結果、テストを書かなくてもいい流れになった。
  • 視覚的にテスト対象のUIが見れなかったため、結局のところデザイナーはアプリケーションになったものしか見なくなってしまった。
  • ビジネスサイドの人に確認し、意図のズレを把握するような調整をしなかった。

つまり、コラボレーションを生むという課題に対して、ATDDという手段だけ導入し、コミュニケーション構造の変化に取り組まなかったことが原因でした。

では、どうすれば良いのか。先ほどのコンウェイの法則に対して、「逆コンウェイ戦略」で考えてみます。

つまり、

ソフトウェアの理想形から逆算した、組織のコミュニケーション構造を形成することによって、結果的に理想的なソフトウェアになることを目指す

逆コンウェイは一般的に有効性があると言われていますが、テスト文化の醸成にも、これが有効なのではないかと考えています。

手段としてのテストを導入し、一時的に実行できたとしても、組織を変えていかないとテスト文化は定着しない。であれば、組織のコミュニケーション設計を理想の形に変えることが、テスト文化醸成につながるはずです。

4. Gaudiyが失敗から得た学びと改善

ここからは、Gaudiyが失敗から得た学びをいかして、どんな改善に取り組んでいるかをご紹介します。

特に、フロントエンドのテスト改善としては、以下に取り組んでいます。

  • エンジニア以外が使い方や有効性を理解できる環境をつくる(完了)
  • レビューの構造と参加者を変更する(途中)
  • 受け入れ条件を調整する(途中)

テストを書くことや、良いテストであることは重視せず、現在はステークホルダーが実際に "参加する" ことにこだわっています。

特に、エンジニア以外が使い方や有効性を理解できる環境づくりに対して、実際に取り組んだ例を挙げてみます。

フロントテストでは、テスト結果の状態を誰でも見られるように、CSF3.0とinteraction storyを活用することがとても有効であると考えています。(詳細は、以下の記事が詳しいのでご参考ください。)

zenn.dev

zenn.dev

これをPRごとにstorybookをデプロイすることで、

f:id:hanahanayaman:20220225015930p:plain

f:id:hanahanayaman:20220225015945p:plain

このようにコードを理解していなくても、検証したいパターンを誰でも認識できるようにしています。

f:id:hanahanayaman:20220225020105p:plain

Defaultの状態

f:id:hanahanayaman:20220225020217p:plain

不適切なパスワードを入力したケース

これによって、どのstoryのどの挙動が、本来の意図とどのように違うのかを、誰でも指摘できるようになりました。

5. まとめ

今回は、テスト文化を醸成するためのコミュニケーション設計についてご紹介しました。

現在は、同じチームのフロントエンドエンジニアには意識の変化が起きていますが、まだデザイナーやドメイン理解者とのコミュニケーション構造までは変化しきれていません。今後は、ここを変えていきたいと思います。

テスト文化づくりやコミュニケーションを促進する仕組みづくりに興味がある人がいれば、ぜひお話ししたいです!

meety.net

Gaudiyの技術選定について知りたい方は、以下の記事をご参考ください。

techblog.gaudiy.com

GraphQLにおけるエラーハンドリングの実践

f:id:hanahanayaman:20220217214432p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている高島(@takashima_katsu)です。

Gaudiyでは現在、BFFレイヤとしてGraphQLサーバを利用しています。導入してから1年以上が経ちますが、スキーマ駆動開発はDXの向上につながっていると実感しています。(以下のブログが詳しいです。)

techblog.gaudiy.com

今回は、GraphQLの利点を活かしたエラーハンドリングの方法について、Gaudiyでの実践をもとに書いてみたいと思います。エラーハンドリングの実装について課題感のある人や、現在GraphQL Errorsを使っている人に、ぜひ読んでいただけると嬉しいです。

1. エラーハンドリングとGraphQL

エラーハンドリングとは、プログラム実行時にエラーが生じた際に、すぐにその実行を終了させず、あらかじめ用意しておいた処理を行うことです。これをすることで、意図しない構造のデータが保存されたり、異常終了してしまう事態を防ぎます。

Gaudiyでは、GraphQLでのエラーハンドリングを行っており、そのベストプラクティスを探ってきました。

GraphQLの特徴は、データをモデル化し、スキーマとして定義することです。これによって、APIドキュメントなどを別途作成せずとも、クライアントがイントロスペクションを通じてスキーマの詳細を知ることができ、必要な情報を要求することができる、というメリットがあります。

GraphQLエラーハンドリングにおける一般的な手法としては、以下の errors エントリーにエラーの詳細を含める、GraphQL Errorsがあると思います。

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [{ "line": 6, "column": 7 }],
      "path": ["hero", "heroFriends", 1, "name"],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

これは GraphQL SpecのErrorsセクション から持ってきたものです。このエラー表現を、後述するエラー表現と区別するために、便宜上「トップレベルエラー」と呼びたいと思います。

トップレベルエラーは、GraphQL Specでも説明されていたり、GraphQLサーバの実装でよく使われる Apollo Server のドキュメントでも紹介されているので、よく利用されている表現だと思います。

しかし、ここで考えていただきたいのですが、これはGraphQLの利点を活かすことができているのでしょうか?

今回はその課題提起と、解決策としての実装方法について紹介したいと思います。

2. GraphQL Errorsにおける課題

GraphQLの利点は、先述の通り、スキーマとして定義することで、クライアントがイントロスペクションを通じてスキーマの詳細を把握できる点にあります。

ですが、トップレベルエラーには、このスキーマがありません。そのため、クライアント側がどういったエラーがあるかを知ることができなかったり、型の自動生成もできなかったりして、別途、ドキュメントの作成やコミュニケーションコストが発生してしまいます。

また実際に運用していく中で、エラーの追加や変更に気がつかず、フロントで適切なエラーフィードバックを出せなくなってしまったり、そもそもエラーによって細かくフィーバックを出すことが億劫になってしまい、抽象度の高いエラーフィードバックを出してしまうこともありました。

結果として、Gaudiyが大事にしている『Fandom』ではない体験の提供につながってしまったり、DXも悪くなってきていると感じていました。

また、 extensions エントリーなどでエラーを拡張したりと便利なことも可能ですが、これもスキーマ外で定義することになるため、同じように別途ドキュメントの作成が必要でした。

3. GraphQLエラーハンドリングの実践

こうした課題に対して、エラーもデータと同じようにモデル化し、スキーマとして定義する方法を取り入れていきました。このスキーマでのエラー表現を、トップレベルエラーと区別するために、便宜上「スキーマエラー」と呼びます。

ここからは、Gaudiyでは実際、どのようにスキーマエラーを実装しているのかについて説明していきます。

3-1. エラーの分類

まずは、エラーを分類します。エラーの種類によっては、今まで通りトップレベルエラーを使った方が良いケースもあり、Gaudiyでも多くのエラーではトップレベルエラーを利用しています。

具体的には、「例外エラー」と「ドメインエラー」の2つに分類しており、前者ではトップレベルエラーを、後者ではスキーマエラーを使用しています。この分類は、GraphQLの作者の1人であるLee Byronも、いくつかのissuesで触れています。

GraphQL errors encode exceptional scenarios - like a service being down or some other internal failure. Errors which are part of the API domain should be captured within that domain.

https://github.com/graphql/graphql-spec/issues/391#issuecomment-385553207

The general philosophy at play is that Errors are considered exceptional. Your user data should never be represented as an Error. If your users can do something that needs to provide negative guidance, then you should represent that kind of information in GraphQL as Data not as an Error. Errors should always represent either developer errors or exceptional circumstances (e.g. the database was offline).

https://github.com/graphql/graphql-spec/issues/117#issuecomment-170180628

「サーバが落ちている」などのシステム系のエラーは「例外エラー」に、「認証情報がない」などのドメインに関するエラーは「ドメインエラー」に分類するようにします。

3-2.ドメインエキスパートへのヒアリング

スキーマエラーの対象となる「ドメインエラー」は、その名の通り、ドメイン知識として扱います。

そのため、どのようなエラーが考え得るかについて、ドメインエキスパートへのヒアリングを通じて、チームで共有することが大事です。 Gaudiyの場合は、実例マッピングや受け入れ基準設定のときに、どういった失敗ケースがあるのかを洗い出しています。

その後、 どのようなフィードバックを出すのがユーザー体験として良さそうかを、CSやデザイナーと議論しながら進めています。

f:id:hanahanayaman:20220217211823p:plain
実際のチケット

これは、最近「シリアルコードを入力してNFTを受け取れる」という機能を実装した際の、実際のチケットです。実例マッピングをして、受け入れ基準の設定まで行いました。(Gaudiyではこのように、ユーザーストーリーベースでチケットに書くようにしています。)

どういった失敗ケースがあるのかをチケットの受け入れ基準に書いていますが、それをそのままスキーマで定義します。

"""
エラー: 該当しないシリアルコードの場合
"""
type CheckSerialCodeNotApplicable {}

"""
エラー: 既に使用されているシリアルコードの場合
"""
type CheckSerialCodeAlreadyUsed {}

"""
エラー: シリアルコードの入力回数が上限を超えている場合
"""
type CheckSerialCodeUsageLimitExceeded {}

3-3. Union を使った Result 型の作成

先ほど定義したスキーマをもとに、Result型を作成し、オペレーションタイプの返り値として返す方法を採用しています。

こちらの方法は 『200 OK! Error Handling in GraphQL』 で詳しく説明されているので詳細は省きますが、以下のように定義することができます。

type Mutation {
  """
  シリアルコードの入力チェック
  """
  checkSerialCode(serialCode: String!): CheckSerialCodeResult!
}

union CheckSerialCodeResult =
    CheckSerialCodeSuccess
  | CheckSerialCodeNotApplicable
  | CheckSerialCodeAlreadyUsed
  | CheckSerialCodeUsageLimitExceeded

"""
成功
"""
type CheckSerialCodeSuccess {}

"""
エラー: 該当しないシリアルコードの場合
"""
type CheckSerialCodeNotApplicable {}

"""
エラー: 既に使用されているシリアルコードの場合
"""
type CheckSerialCodeAlreadyUsed {}

"""
エラー: シリアルコードの入力回数が上限を超えている場合
"""
type CheckSerialCodeUsageLimitExceeded {}

この方法は、複数のエラーを同時に返せないなどの制約はありますが、シンプルな実装になっています。

また、複数のエラーを同時に返したい場合などは、『A Guide to GraphQL Errors』 の Error Union List の方法が参考になると思います。

mutation Mutation($serialCode: String!) {
  checkSerialCode(serialCode: $serialCode) {
    ... on CheckSerialCodeSuccess {

    }
    ... on CheckSerialCodeNotApplicable {

    }
    ... on CheckSerialCodeAlreadyUsed {

    }
    ... on CheckSerialCodeUsageLimitExceeded {

    }
  }
}

このようにスキーマエラーを使うことで、フロントはスキーマの詳細を知ることができ、 __typename の分岐でエラーフィードバックのハンドリングを行うことができるようになります。

4. まとめ

この記事では、Gaudiyで実践している、GraphQLのエラーハンドリングの方法についてご紹介しました。

エラーを「例外エラー」と「ドメインエラー」に分類し、ドメインエラーをスキーマとして定義することで、 DXの良いハンドリングを行うことができます。ドメインエラーはドメイン知識とイコールなので、ドメインエキスパートへのヒアリングを通じて洗い出していくことが大事です。

GraphQLの特性を活かしたエラーハンドリングの仕方として、ご参考になれば嬉しいです。この辺り興味ある方いれば、ぜひお話ししましょう!

https://meety.net/matches/YEieGYUZDYhr

Gaudiyの技術スタックやその選定思想については、こちらの記事をご参考ください。

techblog.gaudiy.com

エンジニアがCSチームとのコラボレーションで大切にしていること

f:id:hanahanayaman:20220207120112p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている永井(@sho0910K)です。

Gaudiyではここ数ヶ月、CSチームとエンジニアチームのコラボレーションがうまく回り始めていると感じています。

GaudiyにおけるCSチームは、Gaudiyが提供するファンコミュニティでユーザーさんのサポートや体験づくりを担当しているチームです。 社内では「コミュニティチーム」と呼んでいますが、一般的にはCS(カスタマーサポート、カスタマーサクセス)チームが近いと思いますので、今回は「CSチーム」と呼ばせていただきます。

先日公開した2022年の抱負blogにある「プロダクト主導型組織」としてはまだまだ改善すべきところは多いですが、以前に比べればCSチームとエンジニアチームのコラボレーションは多くなってきており、CSチームを通してエンジニアチームにもユーザーさんの声がよく届くようになってきていると感じています。

そこで今回は、CSチームとうまくコラボレーションするために、エンジニアとして大切にしていることをご紹介したいと思います。

エンジニアとCSチームの連携がうまくいっていないと感じている方、プロダクトの改善がユーザーさんに届いているか不安に思っている方の改善の参考になれば幸いです。

1. CSチームとのコラボレーションで大切にしていること

より良いプロダクト開発を進めるためには、CSチームとのコラボレーションは不可欠です。その連携において、エンジニアとしては次のことを大切にしています。

  1. フィードバックをプロダクト目線で捉える
  2. ユーザーさんにプロダクトの改善を届ける
  3. エンジニア視点でのみ話さない

1-1. フィードバックをプロダクト目線で捉える

CSチームからはユーザーさんの率直な意見がたくさん共有されますが、これを受け止める際には「プロダクト目線」を大切にしています。

Gaudiyの提供するコミュニティアプリは、共通基盤をもつワンプロダクトですが、IPごとに別々のファンコミュニティとして提供されています。 そのため改善に関しては、特定のコミュニティでのみ考えるのではなく、コミュニティアプリというプロダクト全体に関わる改善として考えています。

そこで大切なのは、フィードバックとして挙げられた要望の背景をエンジニアとしても理解することです。 背景を理解した上で、最適な設計に落とし込めるようにPdM・エンジニア含めて議論しています。

1-2. ユーザーさんにプロダクトの改善を届ける

フィードバックを元にプロダクトの改善を行ったら、その改善をユーザーさんにきちんと届けることが大切です。 プロダクトの改善は、困っていたユーザーさんに改善された旨が伝わり、再度使っていただいた上で実際に改善されたとわかっていただくまでがゴールだと考えています。

これにはCSチームとのコラボレーションが不可欠で、「今回のリリースでは何を改善したのか」をCSチーム宛に連携することで、ユーザーさんにも改善の旨を伝えてもらっています。

1-3. エンジニア視点でのみ話さない

僕の所属するエンジニアチームでは、週の初めに一週間分の開発スプリントを決めていますが、このミーティングにはCSチームも参加しています。実際のユーザーさんの投稿を参考にして、優先度や対応する項目を議論しています。

この議論の際には、エンジニア視点だけで話さずに、実際にコミュニティを使う側を想定して話したり・技術的な用語を噛み砕いて話したりしています。

2. 以前はCSチームとのコラボレーションはうまくいっていなかった

そもそもの背景として、半年ほど前はCSチームとエンジニアのコラボレーションがうまく回っていませんでした。 具体的には、以下の課題を抱えていました。

  1. ユーザーフィードバックの優先度があがらない
  2. CSチームから声があがりづらくなる
  3. フィードバックに対応するエンジニアが偏る
  4. プロダクトの改善がユーザーに届いてない

2-1. ユーザーフィードバックの優先度があがらない

Gaudiyはまだまだリソースの多くない組織です。そのため、事業的な開発リソースと運用上でてくる改善や問題への対応のリソースの配分において、どうしても事業進捗に関わる部分の開発のほうが優先されている時期がありました。そんな中では、せっかくCSチームからあがった改善の対応に関しても優先度が上がりづらくなっていました。

2-2. CSチームからの声があがりづらくなる

開発のスプリントとして優先度が落ちてしまうと、スプリントを決める会において、CSチームから発言や改善要望がなかなかあがりづらい状況になっていました。実際、声をあげたとしても受け入れられるかわからないという感覚をCSチームに与えてしまっていたと思います。

2-3. フィードバックに対応するエンジニアが偏る

CSチームから声が上がりづらい状況になったために、突発的なフィードバックに対応するエンジニアも限られていました。当時はエンジニアチームとCSチーム間のコラボレーションも、限られたメンバーで行うなどの偏りがあったため、そこに関わっているメンバーしか自発的に動かないような状況でした。対応をお願いしたとしても「やらされている感」を感じさせてしまっていたと思います。

2-4. プロダクトの改善がユーザーに届いてない

さらに、フィードバックを受けてプロダクトに反映し改善版リリースを行ったとしても、それがユーザーさんに届いていないことがありました。 CSチームがその改善がリリースされたことに気づいていない、ユーザー告知するリリース内容から漏れてしまうといった問題がありました。

3. 改善のきっかけは率直なフィードバックを求めたこと

そんなモヤモヤした状況でしたが、その流れが吹っきれたのは、取締役でPdMを担う後藤からの「CSチームは率直にユーザーさんの声をエンジニアチーム宛に伝えた方がいいと思います」という一言でした。

僕自身もここにモヤモヤを感じていたため、すぐさま賛同しぜひにと相槌を激しく打ったものです。 そしてこの日を境に、Slackの#mimamoriチャンネルから来る通知の量が格段に多くなりました。

4. CSチームとのコラボレーションで実施してること

  1. ラフにユーザーさんの報告や改善を投稿できる場作り
  2. リリース内容の共有
  3. Whyの明確化

4-1. ラフにユーザーさんの報告や改善を投稿できる場作り

CSチームを通してのユーザーさんからの報告は気軽さを優先して、Slackのmimamoriチャンネルに投稿してもらうようにしています。 投稿のフォーマットも現在は設けておらず、かなりラフに投げていただいています。

f:id:hanahanayaman:20220207120042p:plain
#mimamori_改善報告チャンネルでの投稿

この投稿に特定のスタンプを付けることで、Shortcutというチケット管理ツールに自動登録されるようにしており、バックログリファインメントの際に確認できるようにしています。

4-2. リリース内容の共有

リリース内容の共有は、Slackのワークフローを使って情報連携を行っています。

f:id:hanahanayaman:20220207114254p:plain
リリース内容や開発担当者をSlackで連携

リリース内容を確認できるプレビュー環境も共有することで、今回のリリースでどのような内容が更新されるのかを、CSチームのメンバーが実際のプロダクトを触りながら確認できるようにしています。

4-3. Whyの明確化

CSチームから改善要望や施策の相談があがった際には、背景を理解することを意識しています。 その改善や施策が求められている背景は何なのか、一番良い解決策やプロダクトの将来性も含めて議論できるようにしています。

これに関しても、Slackの投稿スレッドでCSメンバーとエンジニア、そしてPdMを交えて活発にやり取りしています。

f:id:hanahanayaman:20220207115050p:plain
実際にWHYを確認するやり取りの一部

5. CSチームとのコラボレーションからの学び

以前はCSチームからの報告に対応するエンジニアは限られていましたが、上述したような工夫をしたことで、これまで参加していなかったエンジニアもCSチームとの会話に入ってきたり、報告をキャッチアップしてWhyを聞きに行ったりと、とても自律的に動くメンバーが増えてきたと感じています。

これはCSチームのメンバーが率直にユーザーさんのフィードバックを届けてくれるようになり、Slack上でのフィードバックや改善に対する議論が盛んになったからだと思います。

6. さいごに

Gaudiyのバリューのひとつに「Fandom」という考えがあります。これはあらゆるステークホルダーに最高のファン体験を届ける、というものです。

まだまだプロダクト主導型組織として足りてないところは多いと思いますが、ひとつでも多くユーザーさんにFandomを届けられるように、よりエンジニアチームとCSチームのコラボレーションを濃くしていきたいと思っています。

Gaudiyで一緒にユーザーさんにFandomを届けたい方(エンジニアやカスタマーサクセス問わず)や、CSチームとの連携で同じような課題感を持っているエンジニアの方、ぜひお話しましょう!

meety.net

Gaudiyの技術スタックやその選定思想については、以下記事をご参考ください。

techblog.gaudiy.com