REST と GraphQL — 何を楽にして、何を難しくするか
過不足のない取得という利点の裏で、キャッシュ・認可・負荷制御がクライアント任せから自分の責任に移る。
この記事の進み方
What — 同じ画面を作るときの違い
リソースごとに URL が分かれる。過不足は出るが、HTTP の仕組みがそのまま使える。
GET /articles/123
GET /articles/123/author
GET /articles/123/comments?limit=10
→ 3往復(HTTP/2 なら並列で流せる)
→ それぞれ独立に CDN キャッシュできる
→ 使わないフィールドも返る(オーバーフェッチ)
→ 足りなければもう1回呼ぶ(アンダーフェッチ)- 往復回数
- リソースの数だけ
- 転送量
- 不要な分も含む
- CDN キャッシュ
- そのまま効く
- 認可の実装
- エンドポイント単位
- 負荷の上限
- 設計時に決まる
- –HTTP のエコシステム(キャッシュ・監視・レート制限)がそのまま使える。
- –画面ごとに専用エンドポイント(BFF)を作れば、往復を1回にできる。
GraphQL は取得を1往復に畳む。REST は URL ごとに分かれる。この違いが、キャッシュ・認可・負荷制御のすべてに波及する。
GraphQL が持ち込む3つの責任
- 1① N+1 対策(DataLoader)階層ごとにリゾルバが呼ばれる構造的な問題重い
- 2② クエリの複雑度制限深いネストや大量取得を拒否する重い
- 3③ フィールド単位の認可誰がどのフィールドを見てよいか重い
- 4④ キャッシュ戦略HTTP キャッシュが使えない分の代替中
- 5⑤ 監視とレート制限1リクエストの重さが一定でない中
これらを用意せずに公開すると、冒頭の事故(キャッシュ消失・DB 飽和)が起きる。導入コストの本体は、スキーマ定義ではなくここ。
REST なら HTTP やフレームワークが提供していた機能を、GraphQL では自分で組み立てることになる。「導入して終わり」ではない。
GraphQL で CDN キャッシュが効きにくいのはなぜですか?
Why — どちらが優れているかではない
GraphQL は2012年に Facebook が作りました。動機は明確で、モバイルアプリの画面ごとに必要なデータが違いすぎたことです。
- 画面が増えるたびに専用エンドポイントを作ると、API が増え続ける
- 汎用エンドポイントにすると、どの画面でも使わないデータまで返る
- モバイルの回線は遅く、往復も転送量も削りたい
- アプリのバージョンによって必要なフィールドが違う
**「クライアントが必要なものを宣言する」**という発想は、この状況への合理的な回答でした。
しかし、その柔軟性はサーバーが持っていた制御権をクライアントに渡すことで得られています。渡した分だけ、制御の責任がサーバー側に残ります。
「REST は往復が多い」への反論
REST の欠点として挙げられる往復回数は、BFF(Backend For Frontend)でかなり解消できます。
GET /screens/article-detail?id=123
→ 記事 + 著者 + コメント10件を1回で返す
画面ごとに専用のエンドポイントを作る形です。往復は1回、転送量も過不足なし。GraphQL の利点の多くがここで得られます。
代償は「画面が増えるたびにエンドポイントが増える」こと。画面の種類が少なく、変更頻度も低いなら、BFF のほうが単純で安全です。
画面が数十種類あり、クライアントが複数(Web / iOS / Android / 提携先)ある場合に、GraphQL の価値が出てきます。
エラーとステータスコード
GraphQL は原則として HTTP 200 を返し、エラーは errors 配列で表現します。
HTTP 200 OK
{
"data": { "article": null },
"errors": [{ "message": "Not found", "path": ["article"] }]
}
これはエラー設計の章で見た「すべて 200 で返す」問題そのものです。監視・ロードバランサ・CDN が異常を検知できません。 GraphQL を採用するなら、エラー率の監視を errors 配列を見る形で作り直す必要があります。
転送量が40%減ったのにサーバー負荷が10倍になりました。何が起きていますか?
演習 — まず自分で判断する
解説を読む前に、まず自分で判断してみてください。ここで一度詰まっておくと、 次の節の判断軸が「なるほど」ではなく「そう来たか」に変わります。
この2つのサービスに、それぞれどちらを選びますか?
- 【サービスA】料理レシピの閲覧サイト。月間 3000 万 PV
- ・クライアントは Web(レスポンシブ)のみ
- ・8割が未ログインの閲覧で、コンテンツは誰が見ても同じ
- ・テレビ紹介時に特定ページへ数万 PV/分が集中する
- ・画面の種類は10程度で、変更頻度も低い
- 【サービスB】社内の統合ダッシュボード
- ・クライアントは Web / iOS / Android / 提携先の外部システム
- ・画面が 60 種類以上あり、毎月新しい画面が追加される
- ・画面ごとに必要なデータの組み合わせがまったく違う
- ・すべてログイン必須で、社内ネットワークからのみアクセス
- ・同時利用者は最大 500 人程度
- · キャッシュが可用性にどれだけ寄与しているか
- · クライアントの数と、画面の変更頻度
- · 利用者を信頼できるか(負荷制御の必要性)
「GraphQL にすれば過不足なく取れて速くなる」という提案に、一緒に決めるべきことを説明してください
- 相手は転送量の削減を根拠にしている
- 現在は CDN でレスポンスをキャッシュしている
- 採用を否定せず、必要な準備を洗い出したい
読み終わりましたか?
読了にすると、これを前提とする記事がロードマップで開放されます。