定義
GraphQL(グラフキューエル)は、2015年にMeta(旧Facebook)がオープンソース化したAPIのクエリ言語およびランタイムです。従来のREST APIが「エンドポイントごとに固定されたデータ構造」を返すのに対し、GraphQLではクライアント側が必要なフィールドだけを指定して1回のリクエストで取得できます。
DTC/EC文脈では、フロントエンド(Next.js、Nuxt、Shopify Hydrogenなど)とバックエンド(商品DB、在庫、決済、CMS、CRM)の間を仲介するBFF(Backend for Frontend)層として採用されるケースが急増しています。Shopify Storefront API、Commerce Layer、Saleor、BigCommerce GraphQL APIなど、主要Headlessコマースプラットフォームは軒並みGraphQLを標準採用しています。
类比:レストランの注文方式で理解する
REST = 定食メニュー
「Aランチ」を頼むと、スープ・サラダ・メイン・ライスが必ずセットで出てきます。サラダが要らなくても、必ず付いてくる。これがOver-fetching(過剰取得)です。逆に「メインだけ大盛りで、デザートも追加したい」となると、複数の定食を注文する=複数エンドポイントへのリクエストが必要になります。
GraphQL = ビュッフェ形式
自分で「サラダは省いて、メインを2倍、デザートはチーズケーキだけ」と1枚の注文票に書いて渡す。厨房(サーバー)はその注文票どおりに1回で皿を返します。これがUnder-fetching/Over-fetchingを同時に解決するGraphQLの本質です。
ECサイトで言えば、「商品詳細ページ」を表示するのに、REST では /products/:id、/inventory/:id、/reviews?product_id=:id、/recommendations/:id と4回叩くところを、GraphQLなら1リクエスト・1ラウンドトリップで完結します。
公式・構造
GraphQLのリクエストは本質的に単一エンドポイント(通常 /graphql)へのPOSTです。
POST /graphql
{
product(id: "gid://shopify/Product/123") {
title
priceRange { minVariantPrice { amount currencyCode } }
variants(first: 10) {
edges { node { id sku quantityAvailable } }
}
}
}
レスポンスはリクエストの形と1:1で対応します(これを「shape matching」と呼びます)。
{ "data": { "product": { "title": "...", "priceRange": {...}, "variants": {...} } } }
パフォーマンス計算の基本式
RESTでの総レイテンシ:
T_rest = N × (RTT + S)
GraphQLでの総レイテンシ:
T_graphql = RTT + S_composite
- N = エンドポイント数(REST)
- RTT = 1ラウンドトリップ時間(例:モバイル4Gで 120ms)
- S = 各APIのサーバー処理時間(例:80ms)
- S_composite = リゾルバ統合後の処理時間(例:150ms、DataLoaderによるバッチで最適化)
具体例:商品詳細ページで4エンドポイントを叩く場合
- REST:4 × (120 + 80) = 800ms
- GraphQL:120 + 150 = 270ms
- 削減率:約66%
REST vs GraphQL 比較表
| 項目 | REST API | GraphQL |
|---|---|---|
| エンドポイント | リソースごとに複数(`/products`, `/orders`…) | 単一(`/graphql`) |
| データ取得 | サーバーが固定構造を返す | クライアントが必要フィールドを指定 |
| Over-fetching | 発生しやすい | 原理的に発生しない |
| Under-fetching | 複数回リクエストが必要 | 1回で完結 |
| バージョニング | `/v1/`, `/v2/` が必要 | フィールド単位のDeprecation |
| キャッシュ | HTTPキャッシュが容易 | 難(Persisted Queryで対応) |
| 学習コスト | 低い | 中〜高(Schema/SDL理解必須) |
| 向く用途 | シンプルなCRUD、公開API | 多様なクライアント、Headless EC |
| 代表例 | Shopify Admin REST | Shopify Storefront API |
DTC/ECでの具体的な応用シーン
1. 商品詳細ページ(PDP)の高速化
- 商品情報・バリエーション・在庫・レビュー・レコメンドを1クエリで取得
- Shopify Hydrogen採用ブランドでは、PDPのLCP(Largest Contentful Paint)が2.8秒 → 1.4秒に改善した事例あり
2. カート・チェックアウトの動的制御
- カート内の商品ごとに「在庫切れ間近」「割引適用可能」などのフラグを必要な分だけ取得
- 決済前に在庫の再検証クエリを1回で実行
3. マルチデバイス対応
- モバイル:title, price, thumbnail のみ取得(約2KB)
- デスクトップ:description, specs, reviews, relatedProducts も取得(約18KB)
- 同じスキーマでペイロードを9倍差に調整可能
4. パーソナライゼーション
- ログインユーザーの購買履歴・会員ランク・クーポン残高を1クエリで統合表示
よくある誤解・落とし穴
❌ 誤解1:GraphQLはRESTより常に速い
→ 正しくは「往復回数とペイロードを最適化する」技術。単純な1リソース取得ならRESTの方が速いこともある。N+1問題をDataLoaderで解決しないと、むしろ遅くなる。
❌ 誤解2:キャッシュは自動で効く
→ HTTPレベルのCDNキャッシュは効きにくい。Persisted Query(APQ) や CDN + GETリクエスト化 が必須。Shopify Storefront APIは独自のコスト計算(1クエリあたり最大1,000ポイント)を採用。
❌ 誤解3:何でも1クエリで取ればいい
→ クエリが深すぎるとDoSリスク。Depth Limit、Query Cost Analysis、Rate Limiting を必ず設定。Shopifyはリーキーバケット方式(毎秒50ポイント回復) で制限。
❌ 誤解4:スキーマ設計は後回しでいい
→ Headless ECではスキーマがフロント・バック・モバイルの契約になる。後からの破壊的変更は全クライアントに影響。Schema Registry と Codegen をCIに組み込むのが業界標準。
❌ 誤解5:RESTを全部置き換えるべき
→ 決済Webhook、画像配信、CSV一括出力などはREST/HTTPの方が適する。ハイブリッド構成が現実解。
関連术语
- Headless Commerce — フロントとバックを分離したECアーキテクチャ
- BFF(Backend for Frontend) — GraphQLが活躍する中間層
- Apollo Client / urql / Relay — 代表的なGraphQLクライアント
- DataLoader — N+1問題を解決するバッチ・キャッシュライブラリ
- SDL(Schema Definition Language) — GraphQLスキーマ記述言語
- Persisted Query(APQ) — クエリをハッシュ化して通信量削減
- Shopify Storefront API — DTCで最も普及しているGraphQL EC API
- Federation / Stitching — 複数GraphQLサービスを統合する手法
- REST / gRPC — 比較対象となる代替API技術
GraphQLは「銀の弾丸」ではなく、Headlessコマースの複雑性を制御するための設計言語です。DTCブランドがオムニチャネル化し、モバイル・Web・店舗・アプリとクライアントが多様化するほど、その価値は指数的に高まります。導入時は「スキーマ設計 → コスト制御 → キャッシュ戦略」の3点を最初に固めることが成功の鍵です。
