Slide 1

Slide 1 text

~ エラーレスポンス設計から考える ~ 0→1開発における GraphQLへの向き合い方 おおいし (@bicstone) 2024/09/10 | GraphQLにどう向き合う?導入と活用の実際 (C) 2024 Oishi Takanori

Slide 2

Slide 2 text

自己紹介 大石貴則 (@bicstone) Certified ScrumMaster® is a certification mark of Scrum Alliance, Inc. Any unauthorized use is strictly prohibited. 高専卒の元機械エンジニア。 インターネットが世の中を変えていく のを目の当たりにしWeb業界に転身。 現在はSaaSの開発を通じて物流業界の 課題解決に正面から向き合っている。 好きなネジはイモネジ。 2

Slide 3

Slide 3 text

宣伝 https://findy-code.io/engineer-lab/bicstone_me 3 Findy Engineer Labにインタビュー記事公開中! 「Findy 大石」で検索!

Slide 4

Slide 4 text

GraphQLは、多種クライアントを想定した 不確実性が高いプロダクト開発に向いている。 しかし、柔軟性が高いが故のカオスを生み出す。 初期段階から設計を型化していくことが重要。 0→1開発におけるGraphQLへの向き合い方 4

Slide 5

Slide 5 text

目次 プロダクトの背景 プロダクトのアーキテクチャと目論見 GraphQL活用の現状 GraphQLを採用したメリット GraphQLを採用したデメリット エラーレスポンス設計 GraphQLの向き合い方 まとめ 1 2 3 4 5 6 7 8 5

Slide 6

Slide 6 text

プロダクトの背景 引用元: https://www.hacobell.com/optimization 配車計画業務をAIで支援し、効率化と属人性解消を目 指した新規事業SaaSのMVPへ向けた開発がスタート 2022年: 物流DXの新プロジェクト立ち上げ * MVP (Minimum Viable Product、実用最小限の製品) 6

Slide 7

Slide 7 text

プロダクトの背景 アルゴリズムやUIの不確実性が存在するため、先行 導入した顧客と共同で仮説検証を実施 顧客からフィードバックを得ながら、アジャイルに プロダクト価値向上を目指す 先行導入顧客と協力しMVPを目指す → 要求の変化に機敏に対応し、 持続的に発展可能な体制が必要 7

Slide 8

Slide 8 text

プロダクトのアーキテクチャと目論見 GraphQL gRPC gRPC Frontend Backend Service A Service B ... TypeScript Go Go Python “持続的に発展可能”をキーワードに技術選定 FE、BEともに静的型付け言語を採用 フロントエンド(FE) - バックエンド(BE) 間の APIにGraphQLを採用 BE - サービス 間の通信はgRPCを採用 8

Slide 9

Slide 9 text

プロダクトのアーキテクチャと目論見 サービス間のコラボレーションにおける コミュニケーションコスト削減 多種クライアントからのアクセスを想定 スキーマから型を生成し型安全性の担保 ハコベルとしては初めてGraphQLを採用 GraphQL gRPC gRPC Frontend Backend Service A Service B ... TypeScript Go Go Python 9

Slide 10

Slide 10 text

GraphQL活用の現状 356 回 スキーマのコミット回数 2224 行 スキーマの行数 2022年3月~2024年9月の実績 11 個 Query 69 個 Mutation 10

Slide 11

Slide 11 text

GraphQLを採用したメリット 1. スキーマ駆動開発が実現 2. クライアントからクエリライクに取得可能 3. 変更の影響範囲が型で検知可能 4. Dataloaderによる効率的で安全なデータ取得 11

Slide 12

Slide 12 text

GraphQLを採用したメリット スキーマをベースにした設計議論が促進 スキーマファイル自体が立派なドキュメントになる スキーマが先行して決まることでFE, BEが並行して 作業を進めることが可能 API設計がBEに依存せずボトルネックが解決 1. スキーマ駆動開発が実現 → API設計におけるコミュニケーションコスト が削減されスムーズな開発が実現 12

Slide 13

Slide 13 text

GraphQLを採用したメリット FEは必要なフィールドを束ねて取得可能 1リクエストで済み、オーバーフェッチも阻止 UIの変化があってもFEが呼び出すクエリを変 更するのみで完結 呼び出しの変更はBEの実装変更が不要 2. クライアントからクエリライクに取得可能 → 要求の変化に対し、最小限度の実装で 応じることができ、変更コストが最小化 13

Slide 14

Slide 14 text

GraphQLを採用したメリット ライブラリを用いることで型生成が可能 TypeScript: GraphQL-Codegen [1] Go: gqlgen [2] スキーマ変更の影響範囲を型制約として静的 に検出可能 3. 変更の影響範囲が型で検知可能 → 仕様やモデルの変化を迅速かつ安全に 反映でき、アジリティが向上 14 1: https://github.com/dotansimha/graphql-code-generator 2: https://github.com/99designs/gqlgen

Slide 15

Slide 15 text

GraphQLを採用したメリット 複数のデータ取得リクエストを単一リクエスト としてバッチ処理される仕組み 永続化のロジックがシンプルになり、コードの 可読性向上 Preload忘れなどのリスクを軽減 4. Dataloader*による効率的で安全なデータ取得 → Query Resolverの実装工数が削減され API実装の高速な開発が実現 15 * https://github.com/graphql/dataloader

Slide 16

Slide 16 text

GraphQLを採用したデメリット Query Resolver, Dataloaderなどの概念/仕様 を習得する必要 仕様が最低限度で柔軟性が高いため、様々な ルールを特性に応じて検討する必要 プロダクトでは設計の見直しが複数回発生 柔軟性が高いが故の設計難易度の高さ → GraphQLのベストプラクティスの習得や スキーマ設計の型化が必須 16

Slide 17

Slide 17 text

GraphQLを採用したデメリット 設計の見直しが続いたため、後追いでDesign Patternsを作成し、設計の意思決定とその結果 を言語化して記録。 エラーレスポンス カスタムスカラ バリデーションの明示 など 柔軟性が高いが故の設計難易度の高さ 17

Slide 18

Slide 18 text

エラーレスポンスの設計 フォームのバリデーション エラーにおける事例 ユーザーフレンドリーかつ 高メンテナンス性を実現し たい プロダクト特性によって最 適な設計は異なる 検討した3パターンを紹介 Mutationにおけるエラーレスポンスの設計 18

Slide 19

Slide 19 text

パターン① 起こり得るエラーをすべてスキーマに表現する エラーレスポンス例 スキーマ例 19 ←返り値がResultに

Slide 20

Slide 20 text

パターン① 起こり得るエラーをすべてスキーマに表現する 返しうるエラーがスキーマから明確 クライアントでエラーに応じた分岐が可能 サーバーでエラー文言の管理が不要 メリット デメリット エラーコードの意味についての合意が必要 スキーマが肥大化し、実装量が増加 → クライアントでエラーハンドリングを 行いたい場合に向いている 20

Slide 21

Slide 21 text

パターン② GraphQL仕様のエラー*と併用する エラーレスポンス例 スキーマ例 ↑スキーマ上には 表現されない 21 * https://spec.graphql.org/October2021/#sec-Errors

Slide 22

Slide 22 text

パターン② GraphQL仕様のエラー*と併用する スキーマの記述量が最小限 GraphQLの仕様を活用するため実装が簡潔 サーバーに閉じているため仕様変更が容易 メリット デメリット クライアントで型を活用できずエラーハンド リングが煩雑 → 実装工数をかけたくない場合に向いている 22 * https://spec.graphql.org/October2021/#sec-Errors

Slide 23

Slide 23 text

パターン③ エラーメッセージをPayloadで返す スキーマ例 エラーレスポンス例 23 ←返り値がPayloadに

Slide 24

Slide 24 text

スキーマの記述量が少ない サーバーに閉じているため仕様変更が容易 致命的エラーとバリデーションエラーが分離 メリット デメリット 起こり得るエラーがスキーマから不明確 → 記述量を減らしつつパターン2のデメリットを許容 できない場合に向いている パターン③ エラーメッセージをPayloadで返す 24

Slide 25

Slide 25 text

エラーレスポンスの設計 プロジェクト開始時、パターン①で実装。しかし、 クライアントにエラーハンドリングが必要なく、 工数がかかるデメリットが顕著。 → プロダクト・チーム特性によって 最適な設計は異なる 25 一旦開発を止めてデザインパターンを議論し、 途中からパターン③への変更を決定

Slide 26

Slide 26 text

エラーレスポンス設計から考えるGraphQLへの向き合い方 早い段階からプロダクトの特性に応じた設計 を行い型化してくことが必要 後からの軌道修正をしやすくするため、当時 の意思決定を言語化して参照可能にする 意思決定をテックブログで社外に公開 https://zenn.dev/p/hacobell_dev 26

Slide 27

Slide 27 text

GraphQLは、多種クライアントを想定した 不確実性が高いプロダクト開発に向いている。 しかし、柔軟性が高いが故のカオスを生み出す。 初期段階から設計を型化していくことが重要。 0→1開発におけるGraphQLへの向き合い方 27

Slide 28

Slide 28 text

Special Thanks ハコベル配車計画チームの皆さん (いつもありがとうございます) GraphQL Error、下から見るか?横から見るか? | by Yosuke Kurami | Medium https://quramy.medium.com/3924880be51f (Quramyさんありがとうございます) 快適にスキーマ駆動開発をするためのGraphQLエラー設計 - バイセル Tech Blog https://tech.buysell-technologies.com/entry/2023/02/21/000000 Shopify GraphQL Design Tutorial https://github.com/Shopify/graphql-design-tutorial/blob/master/lang/TUTORIAL_JAPANESE.md Error States with ErrorBoundaries | Relay https://relay.dev/docs/guided-tour/rendering/error-states/ GitHub GraphQL API documentation https://docs.github.com/ja/graphql Swan | GraphQL API Reference https://api-reference.swan.io/ Finnian Langhamさん - INFRA Original Soundtrack (神ゲーのサントラは資料作成時に流すと捗ります) 大石 貴則 (@bicstone) 登壇資料 & SNS (bicstone.me) 28