Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GraphQLのあまり知られていない魅力 (スキーマの表現力編) / domain model...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
adwd
February 25, 2022
Programming
6.3k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GraphQLのあまり知られていない魅力 (スキーマの表現力編) / domain modeling with GraphQL Schema
adwd
February 25, 2022
More Decks by adwd
See All by adwd
RxJSで状態を管理する / state management by RxJS
adwd
1
1.3k
Savkin先生から学んだぼくの考えた最強のAngularアプリアーキテクチャ / The best Angular application architecture
adwd
1
1.2k
create-react-app-introduction
adwd
7
2k
React/Redux Introduction
adwd
17
5.3k
Other Decks in Programming
See All in Programming
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
160
Vite+ Unified Toolchain for the Web
naokihaba
0
320
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
6.7k
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
400
JavaDoc 再入門
nagise
1
370
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
280
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
140
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.7k
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
200
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
Featured
See All Featured
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
300
My Coaching Mixtape
mlcsv
0
150
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
Statistics for Hackers
jakevdp
799
230k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
220
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Fireside Chat
paigeccino
42
4k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Transcript
GraphQLのあまり知られていない魅力 (スキーマの表現力編) ZOZO Tech Talk #4 - Webフロントエンド×新規事業 株式会社ZOZO
計測プラットフォーム本部 計測システム部 西田 雅博 Copyright © ZOZO, Inc.
© ZOZO, Inc. 株式会社ZOZO 計測プラットフォーム本部 計測システム部 西田 雅博 GraphQL+Reactを極めたい Webフロントエンドエンジニア
Rustもやりたい 2
© ZOZO, Inc. 目次 1. GraphQLとは 2. 一般的に知られているGraphQLのメリット 3. たまたま実感した予想外のGraphQLのメリット
4. こんなGraphQLスキーマです 5. GraphQLスキーマの表現力から得られたメリット 6. まとめ 3
© ZOZO, Inc. GraphQLとは 4
© ZOZO, Inc. GraphQLとは 5 • Meta(Facebook)が開発したクライアントが指定 したデータの形でサーバーがレスポンスを返す クエリ言語 •
https://graphql.org/ • https://spec.graphql.org/October2021/
© ZOZO, Inc. 一般的に知られていそうなGraphQLのメリット • 画面に必要なデータを取得するのに1度のリクエストで済む • リクエスト、レスポンスに静的型が付くのでTypeScriptなどとの相性がいい • GraphiQLやApollo
Sandboxといったプレイグラウンドが便利 • Apollo FederationやSchema Stitchingなどマイクロサービスを束ねる仕組みがある ついでにデメリットも • すべてが POST /graphql になるのでキャッシュや監視のやり方が変わる • クライアント、サーバーともに実装が変わったりと学習コストが必要 6
© ZOZO, Inc. たまたま実感した予想外のGraphQLのメリット • ある新規事業の小さいサービスをREST APIからGraphQLに移行しようとしている • それほど複雑なQuery, MutationがないのでGraphQL特有のメリットはあまりなく、練習くらい
になると思っていた ところが、 • GraphQLスキーマの表現力が高く、REST APIでは表現しきれなかったサーバーとクライアン ト間のドメインロジックが表現できた 7 次のスライドからZOZOMAT for Handsというとある小さいサービスと、そのサー ビスのドメインロジックを表現できたGraphQLスキーマを紹介します
© ZOZO, Inc. 8 • 足のサイズを測ってピッタリのサイズの靴を買えるZOZOMATの指輪版
© ZOZO, Inc. 9 • 足のサイズを測ってピッタリのサイズの靴を買えるZOZOMATの指輪版 • マットの上に手をおいて、音声のガイドに従ってスマホのカメラで色んな 方向から手を撮影すると最適な指輪のサイズを出してくれる •
まだ一般リリースしてなくてこっそりやってます
© ZOZO, Inc. ZOZOMAT for Handsの測定はステップや状態が多い ユーザーに色んな角度から手をスマホで撮影してもらう必要 がある 1.
真上から撮影して左右どっちの手か、マットが平たく置い てあるかなどを判定する 2. マットの色に沿っていろんな角度から手を撮影する 3. 最後に真上からもう一度撮影して完了 このステップごとにサーバーと通信していて、クライアントは今 どのステップにいるのか、次はどのステップかを知る必要があ る 10
© ZOZO, Inc. ZOZOMAT for Handsはエラーがたくさんある • 最初の真上から撮影するとき
◦ 人差し指と中指の間隔が開きすぎている ◦ カメラが手に近すぎる • いろんな角度から撮影しているとき ◦ 指定した色の方向から撮影していない ◦ カメラの角度が高すぎる • などなど • それぞれ対応した音声ガイドを再生するのでエラーハン ドリングが重要 11
© ZOZO, Inc. こんなGraphQLスキーマです 12
© ZOZO, Inc. type Mutation { """ TODOを追加します """ addTodo(text:
String!): Todo } type Todo { id: ID! text: String! status: TodoStatus! foo: FooUnion! } union FooUnion = BarType | BazType | QuxType GraphQLスキーマの基本的な読み方 • Mutation: 実行でデータが変化する操作 ◦ RESTでいうとPUT/POST/DELETE ◦ QueryはGET • addTodoミューテーション ◦ NonNullなStringを引数にとって ◦ NullableなTodoを返す • type Todoで型を宣言 ◦ id, text, status, fooフィールドがある ◦ どれもNonNull • statusはTodoStatus enum • FooUnionは3つのうちいずれかになる 13 enum TodoStatus { TODO DONE }
© ZOZO, Inc. type Mutation { """ processSession 計測ステップを進行します。 sessionIdを指定し、撮影した画像をimageに入れて測定ステップを進めてください。
""" processSession(sessionId: ID!, image: Image!): ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted どんなGraphQLスキーマになったか ※説明用に簡略化していますが実際のスキーマと基本的には同じです 14
© ZOZO, Inc. type Mutation { """ processSession 計測ステップを進行します。 sessionIdを指定し、撮影した画像をimageに入れて測定ステップを進めてください。
""" processSession(sessionId: ID!, image: Image!): ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted processSession ミューテーション 15 ダブルクォート3つで囲んだところはdescription コメントのようなものだけどMarkdownも使えるれっきとしたドキュメント GraphQLの型で表現しきれないビジネスロジックは無理せずdescriptionを活用する
© ZOZO, Inc. type Mutation { """ processSession 計測ステップを進行します。 sessionIdを指定し、撮影した画像をimageに入れて測定ステップを進めてください。
""" processSession(sessionId: ID!, image: Image!): ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted processSession ミューテーション 16 descriptionに書いてあるとおりの処理を行うprocessSessionミューテーション ※GraphQLでファイルアップロードは現状できないので、graphql-multipart-requestを使います
© ZOZO, Inc. type Mutation { """ processSession 計測ステップを進行します。 sessionIdを指定し、撮影した画像をimageに入れて測定ステップを進めてください。
""" processSession(sessionId: ID!, image: Image!): ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted processSession ミューテーション 17 processSessionミューテーションの結果はセッションの途中、失敗、完了の3種類
© ZOZO, Inc. union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed |
ProcessSessionCompleted type ProcessSessionProgressed { nextInstruction: CaptureInstruction! } type ProcessSessionFailed { failure: ProcessSessionFailure! } type ProcessSessionCompleted { # このIDで session Query を実行すると測定結果が取得できます。 completedSessionId: ID! } ProcessSessionResult ユニオン 18 processSessionミューテーションの結果は セッションの途中、失敗、完了の3種類
© ZOZO, Inc. union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed |
ProcessSessionCompleted type ProcessSessionProgressed { nextInstruction: CaptureInstruction! } type ProcessSessionFailed { failure: ProcessSessionFailure! } type ProcessSessionCompleted { # このIDで session Query を実行すると測定結果が取得できます。 completedSessionId: ID! } ProcessSessionResult ユニオン 19 セッションの途中の場合は次の測定の指示 enum CaptureInstruction { TOP BLUE # ... }
© ZOZO, Inc. union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed |
ProcessSessionCompleted type ProcessSessionProgressed { nextInstruction: CaptureInstruction! } type ProcessSessionFailed { failure: ProcessSessionFailure! } type ProcessSessionCompleted { # このIDで session Query を実行すると測定結果が取得できます。 completedSessionId: ID! } ProcessSessionResult ユニオン 20 測定ステップ失敗の場合はその理由 enum ProcessSessionFailure { CAMERA_PITCH_TOO_LOW DISTANCE_TOO_CLOSE # ... }
© ZOZO, Inc. union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed |
ProcessSessionCompleted type ProcessSessionProgressed { nextInstruction: CaptureInstruction! } type ProcessSessionFailed { failure: ProcessSessionFailure! } type ProcessSessionCompleted { # このIDで session Query を実行すると測定結果が取得できます。 completedSessionId: ID! } ProcessSessionResult ユニオン 21 測定完了の場合は結果を取得するためのID (結果を出すのに数秒かかるので終わったことだけ通知する)
© ZOZO, Inc. type Mutation { """ processSession 計測ステップを進行します。 sessionIdを指定し、撮影した画像をimageに入れて測定ステップを進めてください。
""" processSession(sessionId: ID!, image: Image!): ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted ここまでのまとめ • processSessionを繰り返し使って計測を進める • processSessionは3パターンの結果を返す • 計測途中、失敗、完了それぞれ次の動作に必要な情報 が入っている 22
© ZOZO, Inc. type Query { """ 計測が完了したセッションを取得します。 """ session(id:
ID!): Session } type Session { id: ID! analysis: SessionAnalysis! } union SessionAnalysis = AnalysisInProgress | AnalysisCompleted | AnalysisFailed 測定結果を取得する session クエリ 23
© ZOZO, Inc. type Query { """ 計測が完了したセッションを取得します。 """ session(id:
ID!): Session } type Session { id: ID! analysis: SessionAnalysis! } union SessionAnalysis = AnalysisInProgress | AnalysisCompleted | AnalysisFailed 測定結果を取得する session クエリ 24 測定の結果が分析途中、分析完了、分析失敗の3パターンにな ることがわかる。 それぞれの型の中身は省略するが、途中なら数秒後クエリを再 実行、完了なら結果を表示、失敗ならエラー表示すれば良いこ とがわかる
© ZOZO, Inc. type Mutation { processSession(sessionId: ID!, image: Image!):
ProcessSessionResult! } union ProcessSessionResult = ProcessSessionProgressed | ProcessSessionFailed | ProcessSessionCompleted type Query { session(id: ID!): Session } union SessionAnalysis = AnalysisInProgress | AnalysisCompleted | AnalysisFailed 測定の一連の流れがスキーマから読み取れる 25
© ZOZO, Inc. GraphQLスキーマの表現力から得ら れたメリット 26
© ZOZO, Inc. ドメインモデリングともいえる議論が活発にできた • 最初はREST APIをそのまま移したようなスキーマだったがGitHubのPR上で100件近いコメン トで盛んな議論ができた🔥 27
© ZOZO, Inc. ドメインモデリングともいえる議論が活発にできた • 最初はREST APIをそのまま移したようなスキーマだったがGitHubのPR上で100件近いコメン トで盛んな議論ができた🔥 • 紹介したスキーマは割とシンプルですが原型はかなり違った
◦ Union、EnumといったGraphQLの型システムの恩恵 ◦ 今回は使ってないですがディレクティブも強力です • 以前のREST APIのときは入社間もないこともあって正直言ってあまりドメインを詳細まで理 解できていなかったが、この議論とGraphQLスキーマからよく理解できた 28
© ZOZO, Inc. DDDのドメインモデリングにも使えるのではないか • 先日読んだDomain Modeling Made Functionalという本はF#の型システムを利用してドメイン モデリングしていた
• GraphQLくらいの型システムでも実現可能と思える • マイクロサービスが境界づけられたコンテキストに該当するならそのコンテキストが外部に提 供する能力を可読性高く表現できる…気がする • GraphiQLやApollo Studioで動作が確認しやすいこと、スキーマのドキュメント性が高いことも ドメインエキスパートにやさしいのでは 29
© ZOZO, Inc. まとめ • 小さなサービスにGraphQLを導入した • 予想していなかった効果として、スキーマの表現力によってドメインに関する議論が盛んに 行えた •
GraphQLおすすめです! 30
None