2025/4/19 GraphQL, Apolloに触れる
なんか昔にもやってたが、記憶がない
日本語版があった
内容が古すぎるmrsekut.icon
JSやし、
GPT-4.iconに生成させたほうが良さそう
0. イントロダクション
cloneする
内容がめっちゃ古そうmrsekut.icon
JSやし
参考程度にしつつ0から作ったほうが良いか
GPT-4.iconにtutorialを生成させた、もはや原型はない
.graphqlに書いてcodegenするスタイルにもする
start/とfinal/というディレクトリがあって親切だ
1. GraphQL Schema を設計して定義する
.graphqlファイルでSchemaを記述
$ bunx graphql-codegen --config codegen.ts
2. データソースとバリデーションを接続する
仮想のDB層を作成(メモリ上)
入出力の検証にvalibotを使う
3. Resolver を実装してサーバを完成させる
Query / Mutation Resolverを書く
valibotと連携する
hono, Apolloでサーバーを作る
honoとApollo serverを組み合わせる方法が不明
$ bun run server/index.ts
試す
code:graphql
query {
books {
id
title
author
}
}
code:graphql
mutation {
addBook(input: { title: "1984", author: "George Orwell" }) {
id
title
author
}
}
おー、動いたmrsekut.icon
4. GraphQL APIサーバを起動しProduction readyにする
corsなどの設定
5. Reactクライアントを構築しAPIと接続する
bunでapollo client動かすのムズイっぽい
具体的には、if (0) { ... }というコードがあり、bunはこれをデッドコードとみなし除去するため、exportsが未定義になり落ちる
code:error
λ bun dev
frontend ReferenceError: exports is not defined
at /path/to/client/node_modules/rehackt/index.js:18:8
patchあてて対応したmrsekut.icon
この辺なに?
GraphQLのクエリ・ミューテーション・サブスクリプションに対応するTypeScript型を自動生成するプラグイン。
CodegenConfigのdotumentsってなに?
ディレクトリおかしい気がするので直したい
不要なpackageを消す
6. Mutationを使ってデータを更新する
useMutationでデータをPOST
Cacheの更新を行う
動いたけど、仕組みがよくわからないなmrsekut.icon
8. Local Stateを管理する
Apollo ClientのReactiveVarでlocal stateを管理
ログイン状態などをlocalに持つ
コレホンマにお前がやること?という気がするmrsekut.icon
graphql/
.graphqlでschemaを定義
このライブラリは基本的に、client向け、server向けに型を生成するのがメインで、実装は生成しない
ただし、一部のpluginは実装を生成してくれるものもある
getする用のreact hooksとか
server/
graphql/で生成した型に基づいて、queryとresolverを自前で書く
GraphQL Yogaがいわゆるgraphql serverの1つで、↑このschemaを読み込んで良い感じにAPIを生成する それをHonoに食わせることでserverができる
client/
これをgraphql/のcodegenに読み込ませて、client/graphql/types.tsに型や実装を生成する
ここに例えば、useGetBooksQueryもあるので、これをReactから呼ぶことで値を取ってこれる
以降、探索的にcursorに生成してもらうかmrsekut.icon
GPT-4.icon
上記チュートリアルでは出てこなかったが、実際にプロダクトで使うなら抑えておくべき概念を列挙して整理しました。
テーマ別に分けて、できるだけ実践的な視点でまとめます!
1. GraphQL設計・運用系
✅ スキーマの拡張・バージョニング
Breaking Changeなしでスキーマを成長させる方法(フィールドの追加、非推奨化)
deprecation(例: @deprecated(reason: "Use newField"))
将来的な型肥大化を防ぐ設計(特にInputType)
✅ フィールド設計粒度(N+1問題)
1クエリで多段リレーション(例:Book -> Author -> Profile)を引くときの注意
DataLoader(N+1を防ぐバッチ処理ツール)の理解と導入
✅ Authorization / Authentication
認可(Authorization)はResolverレベルでかける(例えば「自分が作ったリソースだけ更新できる」)
GraphQL自体はAuth制御を素で持たないので設計要注意
2. Apollo Client運用系
✅ キャッシュ戦略
デフォルトのInMemoryCacheだけでは足りない場合がある
Cache Policy設計(例えば「一部のフィールドだけ最新を取る」など)
Mutation時のcache.modify()、cache.writeQuery(), cache.evict()活用
✅ エラーハンドリング
ネットワークエラー(通信失敗)
GraphQLエラー(スキーマ違反など)
Apollo Clientはこれらを別個に扱う必要がある(error.networkError, error.graphQLErrors)
✅ ローカルOnlyフィールド設計
Local State管理が増えてきたとき、ReactiveVarを細かく分ける設計
ログイン情報、フラッシュメッセージ、ダークモードなどを一元的に扱う戦略
3. 開発体験・運用体制系
✅ Codegen運用ルール
必ず自動化(Git HookやCIに組み込む)
ドキュメントファイル(*.graphql)の命名規則・粒度の統一(1画面1ファイルなど)
Fragment設計(一部だけ再利用するために型もクエリも小さく分割する)
✅ GraphQLエンドポイント管理
本番・ステージング・ローカルでエンドポイント切り替えをどう管理するか
.envでAPI URLを管理する(Next.jsならNEXT_PUBLIC_つける)
4. Security / Reliability
✅ クエリ制限
最大深さ制限(例:クエリのネストレベルが5以上だとエラーにする)
最大エイリアス数制限(例:Aliasを使って大量リクエストを防ぐ)
レートリミット(ユーザー単位の制限)
Persisted Queries(クエリを事前登録して、動的クエリを禁止する)
✅ 入力バリデーション強化
サーバサイドのInput Validationは必ず行う(バリデーション抜け穴に注意)
Valibotのスキーマ進化に追従する設計(型→Validation→GraphQLの流れを意識)
5. デバッグ・モニタリング
✅ Apollo Client Devtools
ブラウザ拡張機能でApollo Clientのキャッシュ・クエリ履歴を確認できる
問題が起きたとき、キャッシュ状態・クエリレスポンスを見るのに必須
✅ Server Monitoring
GraphQL Server側もリクエスト量、エラー率、レスポンスタイムをモニタリングする
Yogaなら簡単な統計ログを取れるし、さらにPrometheus/Grafana連携もできる
🧠 さらに一歩進みたい人向け
table:table
項目 内容
:--- :---
Subscriptions WebSocketを使ったリアルタイムデータ配信
BFF(Backend For Frontend)設計 GraphQLをBFFとして設計・運用する