Gaudiy Tech Blog

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

Gaudiy、データ分析チームを立ち上げました。

f:id:gaudiy:20220317165949p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでアナリティクスエンジニア兼データアナリストをしている星野(@mochigenmai)です。

年初に公開したブログでお伝えさせていただきましたが、Gaudiyは今年から「プロダクト主導型の組織づくり」を進めています。

techblog.gaudiy.com

プロダクト主導型の組織には、データドリブンな意思決定が欠かせません。そこでGaudiyでは、データを元にしたプロダクト改善を行い、ユーザへの適切な価値提供をしていくために、1月にデータ分析チームを立ち上げました

今回のブログでは、データ分析チームを立ち上げた背景や、立ち上げ時の課題や取り組み、データアナリストの役割などについてお伝えします!

スタートアップで同じようにデータ分析チームの立ち上げを担っている方や、データ分析チームの役割に興味のある方にご参考になれば嬉しいです。

1. データ分析チーム立ち上げの背景

GaudiyではIP(知的財産コンテンツ)を有するエンタメ企業(以下、IPホルダー)に対して、IP公式のファンコミュニティサービスを提供しています。

ビジネスモデルとしてはBtoBtoCであるため、プロダクト開発においては「IPホルダーが他のIPホルダーに」「IPのファンが他のファンに」オススメしたくなるような、toB、toC双方の視点での磨き込みや仕掛けが必要です。

Gaudiyでは今まで、メンタルモデルを深掘るなどの定性リサーチを活かしたプロダクトづくりに取り組んできました。

techblog.gaudiy.com

こうした定性分析の強みはありつつも、プロダクト主導型の組織に移行するにあたって、より定量的なプロダクトの評価・改善が必要なフェーズになってきました

また、データ分析は社内の意思決定だけでなく、IPホルダーとファンからのプロダクト評価にも直結します。そこに組織として注力していきたいという背景から、データ分析チームを立ち上げることになりました。

2. Gaudiyがデータを重視する理由

Gaudiyのプロダクト開発において、なぜデータが重要なのかについて、ファンとIPホルダーそれぞれの視点から少し説明したいと思います。

2-1. ファンにとって居心地のよいコミュニティづくり

ひとつは、ファンにとって居心地のよいコミュニティをつくるためのデータ分析です。

ファンコミュニティの分析において、参考にさせていただいたのが@kengoiwt さんのnoteです。

note.com

コミュニティに参加しているユーザーを、Leader・Follower・Active Audience・Non-active Audienceという4つのセグメントに分けます。

  1. Leader
    • リーダーシップがある
    • 何らかのイベントを企画してくれる
    • クラスタをリードしてくれる
  2. Follower
    • リーダーの企画に賛同している
    • クラスタのメンバーと共に活動を行う
  3. Active Audience
    • クラスタには所属していない
    • クラスターの活動を見守っている
  4. Non-active Audience
    • 全く活動していない

このうち、LeaderとFollowerで構成される「クラスタ」と呼ばれる小さなグループが複数存在しますが、所属するクラスタが複数あるファンの方が、コミュニティでの活動意義を感じてくれるといいます。

各セグメントではコミュニティに参加している目的が違ってくるので、データ分析を通じてそれぞれのセグメントに適切な価値を提供することで、LeaderやFollowerとして活動してくれるファンが多くなり、居心地のよいコミュニティがつくられると考えています。

2-2. IPホルダーにとってのコミュニティ開設の意義

もうひとつは、IPホルダー(クライアント企業)に、コミュニティ開設による意義を感じていただくためのデータ分析です。

Gaudiyでは、ファンのコミュニティ内の活動と、外部サービスの活動を紐付けることができるDID(分散型ID)という技術を利用して、コミュニティ外のマーケティング支援も実施しています。

note.com

IPホルダーにコミュニティを開設してよかったと感じてもらうには、コミュニティの特性を理解していただいたり、各セグメントごとのユーザ数やクラスタ数、コミュニティ外での活動の傾向といった数値を確認していただくことが大切です。

IPホルダーがそういった情報にアクセスしやすく、見やすいダッシュボードなどを作成する必要があります。

3. データ分析チームの立ち上げで生じた問題と対応

Gaudiyでは、拡張性とスピード感のある開発を行うために、データベースにFirestoreを利用していますが、データアナリストからすると大きな問題が2つありました。

ひとつは、APIを利用してBigQueryにエクスポートを行う時、マスターデータとトランザクションデータでコレクション名が同一の場合、同じテーブルに登録されてしまうという問題です。プロダクト開発上はコレクション名が重複しても問題がないので、この問題が起きてしまっていました。

もうひとつはFirestoreが非構造化データなので、分析をするときの整形処理が複雑になってしまうという問題です。

どちらもデータの整形時にミスをしてしまうと、間違ったデータを利用して分析をしてしまい、意思決定のミスリードを誘発しかねません。

これらの問題を解決するために採用したのが、dbtです。

Ubie ( @sotaron ) さんの datalake, interface, component, datawarehouse, datamart の5層構造を参考にして、各層の役割を以下のように明確化させることによって、スピード感のあるデータ分析基盤の開発と意思決定を実現しています。

  1. datalake層
    • firestoreからエクスポートされるデータそのもの
  2. interface層
    • NULLの除去
    • 日付を日本時間に変換
  3. component層
    • マスターデータとトランザクションデータが一緒になっているテーブルを分解
    • 同じテーブル内のデータを別テーブルで切り分けたいものを切り分け
    • カラムのテスト
  4. datawarehouse層
    • マスターデータとトランザクションデータの結合
  5. datamart層
    • 利用用途に合わせたデータを作成

speakerdeck.com

今後はプロダクトの開発速度を落とさずデータクオリティの担保をより加速させていくためにも、エンジニアの方とNoSQLとRDBの使い分けを進めていきたいと考えています。

4. データ分析チームの役割と今後について

現在、Gaudiyのデータ分析チームは、データアナリストとBizDevを兼務する藤原さん(@rfuj1wara234)と僕の2名体制になっています。

データ基盤の開発に加え、Gaudiyには専任のPdMがいないので、意思決定のサポートだけでなくデータアナリスト自身が意思決定を行うこともあります。

そのため、以下の4つがデータ分析チームが担う役割になっています。

  1. データクオリティ担保のためのデータ分析基盤の開発
  2. ユーザー(ファン)が求める価値の提供
  3. IPホルダーのマーケティング支援
  4. 社内での意思決定のサポート

ユーザーが求める価値の提供やIPホルダーのマーケティング支援については、他チームとこまめにコラボレーションを行いながら業務をしています。ここでは、ユーザセグメントの定義やダッシュボードの整備などをするほか、データドリブンな意思決定を行うのでPdMのような立ち回りもします。

また、社内での意思決定のサポートに関しては、上記以外の内容で社内メンバーが必要と判断したデータ分析を行います。ここでは、ただの集計依頼にならないように、データが必要な背景や期日感をヒアリングした上でサポートしています

現時点では分析依頼を受けていますが、分析基盤を整えて「データの民主化」を行えば、どんな職種の方でもすぐにほしいデータが手に入る状態を作ることができると思います。

なので今後は、SQL勉強会などを開いて、データ分析チームのメンバーがいなくてもデータドリブンな意思決定を行える状態をめざしていきたいと考えています。

5. おわりに

今回は、データ分析チームの立ち上げをテーマに、ご紹介させていただきました。

まだ走り出しのチームで、手探りで進めている部分もありますが、効率的に分析が行えるように立ち上げ初期の段階から分析基盤の開発を行っています。

これからも工夫をしながらデータへの意識を社内に根付かせていきたいと思っています。そして、プロダクト主導の組織の"羅針盤"になるようなチームにしていきます。

この記事を読んで、少しでもGaudiyのデータ分析チームに興味をもってくれた方はぜひお話ししましょう!

meety.net

Gaudiyの技術スタックや思想については、以下のブログをご参考ください。

techblog.gaudiy.com

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

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