GraphQLフェデレーションとは?サブグラフ合成とルーターの実装・採用判断を解説
GraphQLフェデレーションは、別々に動く複数のGraphQLサーバーのスキーマを1つに合成し、クライアントには単一のエンドポイントとして見せる仕組みです。個々のサーバーをサブグラフ、合成後のスキーマをスーパーグラフと呼び、実行時の受け口になるのがルーター。Apollo公式のFederationバージョン一覧を2026年8月5日に確認したところ、掲載されている最新は2.15系(LTS・2026年7月)でした。この記事では3層の役割分担、ディレクティブ、実行経路、rover運用、実装の選択肢、見送り条件を扱います。
まとめ:GraphQLフェデレーションを採用してよい条件と見送る場面
先に結論を置きます。サブグラフが3つ以上あり、それぞれを別のチームが所有していて、クライアントが複数ドメインのデータを1リクエストで欲しがっている。この3条件が揃うならフェデレーションは投資に見合います。チーム境界に沿ってスキーマを分割したまま、クライアントには継ぎ目を見せずに済むからです。「別チームが所有している」が欠けた瞬間、得られるものは薄くなります。
見送ってよい場面もはっきりしています。サービスが2つ以下、あるいは開発チームが単一なら、合成の学習コストとルーターの運用負荷が上回る。Apollo Router Coreのライセンスは Elastic License 2.0 で、これはOSSライセンスではありません。無償枠の制限まで含めた費用設計と、スキーマの所有権をどのチームに置くかの合意を、着手前に済ませてください。
複数サブグラフを1つのスーパーグラフへ合成する仕組みと構成要素
まず登場人物を整理します。ここが曖昧だと、エラー時にどの層の問題か切り分けられません。
サブグラフとコンポジションとルーターが担う3層それぞれの役割
サブグラフは、実際にリゾルバを持つ個々のGraphQLサーバーです。ユーザー、商品、注文といった単位で立て、自分の担当する型とフィールドだけを定義します。コンポジションは、各サブグラフのスキーマを読んで1枚のスーパーグラフスキーマを生成するビルド時の処理。生成物には、どのフィールドをどのサブグラフが解決できるかの対応表が入っています。
ルーターは実行時の入口です。届いたクエリを受け、対応表を見て担当サブグラフへ割り振り、結果を1つのレスポンスに組み立てて返します。GraphQL自体の前提を確認したい場合はGraphQLとは?REST APIとの違い・メリット・デメリットを先に読むと、3層の分担が掴みやすくなります。
スキーマスティッチングやBFFと比べたときの実装上の責務境界の違い
同じ「複数のAPIを1つに見せる」でも、責務の置き場所が違います。スキーマスティッチングはゲートウェイ側に統合ロジックを書く方式で、型のリネームや衝突解決をゲートウェイの設定として持つ。統合の知識が中央に集まるため、サービスが増えるほど設定が肥大します。フェデレーションは逆に、統合の指示をサブグラフ側のスキーマへ書き、ルーターは対応表に従うだけ。ゲートウェイに手を入れずサブグラフを追加できます。
BFFは目的が別です。特定のクライアント向けに画面都合の集約を行う層なので、クライアント非依存の全体グラフであるスーパーグラフとは排他になりません。合成の入力になるスキーマ自体の設計思想はGraphQLスキーマ設計の核心原則に整理してあります。
2026年8月時点のFederation 2.15とルーター最小版の対応
版番号は2系統あります。Federationの仕様バージョンと、それを解釈するルーターのバージョン。独立に上がるため、対応表を見ずに片方だけ上げると起動時に弾かれます。Apollo公式のFederation Changelogを2026年8月5日に確認した時点で、掲載されている最新は2.15系(LTS・2026年7月)でした。コンポジションの実装がRustへ書き直された版で、新しいディレクティブの追加はありません。
2.15系で変わったのは検証の厳しさです。従来は素通りしていた不整合を検出し、エラーメッセージに行番号が出るようになりました。この版はルーター2.16.0以上を要求します。1つ前のLTSは2.12系で、キャッシュ無効化に使う@cacheTagが入り、最小ルーターは2.8.0。2.13系はルーター2.11.0以上、2.14系は2.14.0以上を求めます。
エンティティを跨いで解決するための主要ディレクティブと基本の記述例
実装作業はほぼディレクティブの読み書きに集約されます。
@keyで一意キーを宣言しサブグラフ間で同じ型を共有する書き方
複数のサブグラフが同じ型を扱えるようにする起点が@keyです。型に一意キーとなるフィールドを宣言すると、その型はエンティティとして扱われ、他のサブグラフから参照・拡張できるようになります。書き方は型定義に@key(fields: "id")を付けるだけ。@key(fields: "sku variantId")のように空白区切りで並べれば複合キーになります。
実務で効く仕様が1つ。@keyに含めたフィールドは自動的に共有可能とみなされるため、後述する@shareableを重ねて書く必要がありません。ここを知らないと、合成エラーを無駄なディレクティブ追加で潰そうとして迷走します。
@externalと@requiresと@providesが表す依存関係の3類型
3つとも「他のサブグラフが持つデータ」との関係を表します。@externalは「定義は他にあり、こちらは参照するだけ」という宣言で、単独では意味を持ちません。@requiresは、自分のフィールドを解決するために他サブグラフの値が必要だと示すもの。配送料の計算に商品の重量が要るなら、重量を@externalで受け、配送料フィールドへ@requires(fields: "weight")を付けます。
@providesは方向が逆で、「辿った先の型は他サブグラフを呼ばずにこちらが返せる」という申告です。呼び出し回数を減らせますが、申告した以上は本当に値を返す実装が要ります。返せなければnullが漏れます。
同じフィールドを2つのサブグラフが定義すると、合成は既定でエラーになります。意図的に両方から解決させたいときに付けるのが@shareableで、双方に付けて初めて合成が通る。注意すべきは値の一致で、これは「どちらが呼ばれても同じ値が返る」ことを開発者が保証する宣言であり、システムが検証してくれるわけではありません。値がずれると、クエリの書き方次第で返る内容が変わる不具合になります。
@overrideは権威を明示的に移す指示です。移管先で@override(from: "products")と書けば、ルーターはそちらから値を取る。旧サブグラフのコードを消す前に切り替えられるため、モノリスからの段階移行で最も出番があります。公開範囲を絞るなら@inaccessibleでスーパーグラフから隠し、@tagで配布先を分けます。
ルーターがクエリプランを組み立ててサブグラフを呼ぶ実行時の経路
実行時に何回どのサブグラフが呼ばれるかを把握していないと、性能問題の原因を追えません。
ルーターがクエリプランを組み立てる手順とサブグラフ呼び出しの順序
ルーターはクエリを受け取ると、スーパーグラフスキーマから各フィールドの担当を引き、依存関係に沿って実行順序を決めた設計図を作ります。これがクエリプランです。並列に叩ける部分は並列、@requiresのように前の結果が要る部分は直列に並ぶ。プランは同一のクエリ文書に対してキャッシュされるため、生成コストが乗るのは初回だけです。
運用で見るべきなのはプランの段数で、深くなるほどレイテンシは直線的に伸びます。クライアントが投げるのは単一のGraphQLクエリのまま。Apollo Clientとは?GraphQLクライアントの使い方とv4の変更点で扱ったキャッシュの考え方は、ルーターの手前でもそのまま通用します。
_entitiesクエリとリファレンスリゾルバが対応する実体解決
サブグラフを跨いで型を組み立てる中核が_entitiesです。フェデレーション対応のサブグラフはこの特殊なクエリフィールドを自動的に公開し、ルーターは「id=123のUser型を返してほしい」という要求をキーだけの表現で投げます。受け取った側では型ごとのリファレンスリゾルバが呼ばれ、Apollo Serverなら__resolveReferenceという名前になります。
想定より多くのクエリがDBに飛んでいるとき、原因のほとんどはリファレンスリゾルバが1件ずつ呼ばれていることです。_entitiesには複数のキーが配列で渡ってくるため、まとめて引ける実装かを最初に疑ってください。
N+1とタイムアウトが出やすい箇所と実装側で取れる具体的な打ち手
性能が落ちる箇所はほぼ3つです。優先順位を付けて対処してください。
- リファレンスリゾルバの1件ずつ解決。DataLoaderでキーをまとめ1クエリに畳む。ここが最も効きます
- 段数の深いクエリプラン。
@providesで1ホップ減らせないか、スキーマの持たせ方を見直す - サブグラフ1本の遅延が全体を止める構造。サブグラフ単位のタイムアウトを個別に設定する
タイムアウトはルーター側の全体値とサブグラフ個別値の両方を設定します。全体値だけでは、遅い1本に引きずられて他の結果まで捨てることに。ルーターのスパンにサブグラフ名を載せた分散トレースを最初から入れておくと、後追いの調査が要らなくなります。
roverによる合成・スキーマチェック・公開までの運用フロー
事故が起きるのは実行時よりも、サブグラフのスキーマを変更したときです。
rover subgraph publishとスキーマチェックで破壊的変更を止める運用
roverはApolloが配布するCLIで、スキーマの公開と変更の影響検査を担います。基本はCIでrover subgraph checkを走らせ、通ったらrover subgraph publishで送る2段構成。checkは合成が成立するかを見るだけでなく、実際に流れているクエリの記録と突き合わせ、消そうとしているフィールドが直近で使われていないかも判定します。
おかげで、使われているフィールドの削除を機械的に止められます。変更履歴や利用状況はApollo Studioの全体像とGraphQL開発で果たす中核的役割に整理してあります。
supergraph composeによるローカル合成とCIに載せる分担
手元で試すだけならレジストリは要りません。スキーマファイルと接続先URLを並べたYAMLを書き、rover supergraph composeを叩けばスーパーグラフスキーマが標準出力に出る。それをルーターに読ませればローカルで動きます。本番ではローカル合成を開発者の確認用、CIをcheckとpublish、配布をレジストリ経由と3分割します。
クライアント側の型生成をCIに載せているなら、生成の入力をスーパーグラフスキーマに向けてください。GraphQL Code Generatorとは?client presetの設定とv7の変更点で扱った構成なら、スキーマの指定先をルーターのエンドポイントへ変えるだけで、フロントは分割を意識せず型が揃います。
Federation版とルーター最小版とEOS日付を突き合わせる確認手順
版上げで詰まるのは、たいてい対応表を見ていないときです。手順を3つに固定しておくと迷いません。
- サブグラフのスキーマ冒頭にある
@linkのURLからFederation仕様版を読む - 公式のバージョン対応表で、その版が要求するルーター最小版を引く
- 使っているルーター版のサポート期限を告知で確認する
期限は実際に切られています。Apolloのブログ告知によれば、ルーターv1系は1.61.x LTSを含めて2026年3月31日にサポート終了となり、Federation v2.9も同日で終了しました。移行先として案内されたv2.10は2025年12月12日公開のLTSで、保守期間は2026年9月まで。2026年8月時点でv2.10に留まっている環境は、次の版上げ計画をもう立てておく時期にあたります。
Apollo以外の実装とライセンス条件まで含めた選択肢の整理
フェデレーションはApolloが2019年に出した方式ですが、実装は1つではありません。
Apollo RouterとCosmoとHive Gatewayのライセンスと費用比較
選定で最初に確認すべきはライセンスです。Apollo Router Coreは Elastic License 2.0(ELv2)で提供され、Apollo自身が「OSSライセンスではない」と明記しています。無償で使えて改変も再配布もできる一方、競合する商用サービスとしての提供には制限がかかります。
| 実装 | ライセンス | 提供元 | 向く場面 |
|---|---|---|---|
| Apollo Router | Elastic License 2.0 | Apollo | 仕様準拠を最優先する構成 |
| Cosmo Router | Apache 2.0 | WunderGraph | 制限なしで自己ホスト |
| Hive Gateway | OSS(自己ホスト可) | The Guild | レジストリごと自前運用 |
費用も分岐します。ApolloのGraphOSには無償枠があるものの、自己ホストのルーターに毎分60リクエストという上限があり、開発者3人まで、データ保持は1日という条件付きで、本番トラフィックを通す枠ではありません。有償の従量課金は100万リクエストあたり5ドルからと案内されています。この上限に引っかかるなら、Apache 2.0で配布されているCosmoのように機能制限のない実装を先に検討したほうが設計は素直になります。
Composite Schemas仕様が示すベンダー中立の合成規約と差分
合成の規約自体を標準化する動きもあります。GraphQL Foundation の Composite Schemas Spec がそれで、元はChilliCreamが作った仕様をFoundationへ移管したもの。2026年8月5日時点ではドラフト公開の段階にあります。@key、@shareable、@external、@provides、@override、@inaccessibleはApolloと同名で登場します。
違いも明確です。エンティティを引く操作には@lookupという専用ディレクティブが置かれ、依存の宣言は複数形の@requiresではなく@require、公開制御には@internalや@isが加わります。実務への影響を言い切ると、2026年8月時点でこの仕様を理由に実装を選ぶ段階ではありません。押さえるべきは、乗り換えの可能性があるならサブグラフのスキーマに独自ディレクティブを盛り込みすぎない、という設計上の抑制のほうです。
受託開発の現場でフェデレーションを見送る条件と代替となる設計案
技術として成立することと、その案件で採るべきかは別の問題として切り分けます。
サブグラフが2つ以下で開発チームも単一なら見送るという判断基準
採用しない条件を先に固定します。サービス分割が2つ以下で、かつ開発チームが1つなら、フェデレーションは導入しません。この方式が解いている課題は「チームをまたいだスキーマの共同所有」であり、所有者が1チームならその課題は存在しないからです。
代わりの手はあります。1つのGraphQLサーバーの中でスキーマをモジュール分割し、リゾルバをドメインごとのディレクトリに分ける方式です。ルーターの運用も合成のCIも要りません。将来サブグラフへ切り出すとき、モジュール境界がそのまま候補になります。迷ったらデプロイ単位を基準に。別々にデプロイする必要が無いなら、分けないほうが実務では正解になります。
組織の境界とサブグラフの境界がずれたときに起きる典型的な失敗例
最も多い失敗は、技術的な都合でサブグラフを切ったケースです。「読み取り用」「書き込み用」やDBのテーブル群に合わせた分け方がこれにあたる。この切り方をすると、1つの機能追加が常に複数サブグラフの同時変更を要求します。症状も明確で、スキーマ変更のたびに調整会議が要り、rover subgraph checkが頻繁に赤くなり、リリースが相互にブロックされます。
合成のためのディレクティブを足す作業だけが増え、分割前より遅くなる。マイクロサービスとはで語られる分割の原則がそのまま当てはまり、境界はチームと業務ドメインに沿わせる以外に正解はありません。すでにずれた場合は@overrideで正しい所有者側へ1つずつ移し、旧側から参照が消えたことを確認してから削除します。
モノリスから段階的に移行する順序とAPI設計から相談する進め方
既存のGraphQLサーバーがある状態からの移行は、いきなり分割しないのが定石です。まず既存サーバーをそのまま1つ目のサブグラフとして登録し、ルーターを前段に立てる。この時点では中身は今までと同じで、クライアントの向き先だけが変わります。次に切り出したい型へ@keyを付け、新しいサブグラフを立てて@overrideでフィールドを移していきます。
1回のリリースで移すのは1つか2つに留めると、問題が出たときに戻す範囲が小さくなります。どこで切るか、そもそも分割すべきかの判断は、スキーマ設計とチーム構成の両方を見ないと決まりません。既存APIの棚卸しから境界設計、ルーターの運用設計までを含めて相談したい場合は、API開発・システム連携で扱っている領域です。
よくある質問
GraphQLフェデレーションの導入検討でよく挙がる質問を、実装と運用の観点でまとめました。
GraphQLフェデレーションとスキーマスティッチングはどちらを選ぶべきですか?
統合の知識を誰が持つかで選びます。サービスを所有するチームがスキーマの繋がり方まで責任を持てるならフェデレーション、統合専任のチームが中央で面倒を見る体制ならスティッチングでも回ります。ただしスティッチングはゲートウェイの設定が肥大しやすく、サービスが5つを超えたあたりから保守の手数が目立つ方式です。既存構成があるなら、サブグラフ追加のたびにゲートウェイを触るかどうかで判断してください。
Apollo Router以外でFederation 2のスーパーグラフは動かせますか?
動かせます。WunderGraphのCosmo RouterはApache 2.0で配布され、Federation v1とv2のスーパーグラフに対応します。The GuildのHive Gatewayも同様にFederation v2対応をうたい、自己ホストで運用できる実装です。ただしApolloの商用機能に依存した構成をそのまま移せるとは限りません。移行を検討するなら、レジストリ、認証連携、レート制限、トレース連携といった周辺機能の対応状況を1つずつ確認してください。合成そのものは仕様に沿うため、サブグラフ側のスキーマ変更は基本的に不要です。
サブグラフの実装言語がバラバラでも合成できますか?
できます。サブグラフに求められるのは、フェデレーション用のディレクティブを含んだスキーマを公開できることと、_entitiesフィールドに応答できることの2点だけ。言語やフレームワークの制約はありません。Node.js、Java、Go、Python、C#など主要な言語にライブラリが存在します。実務で問題になるのは言語差より、リファレンスリゾルバの一括取得に相当する仕組みが各言語のライブラリで用意されているかどうかです。
Federationを入れるとレスポンスは遅くなりますか?
1ホップ増えるぶんのオーバーヘッドは必ず乗ります。問題はその大きさで、ルーター自体の処理よりも、クエリプランの段数によるサブグラフの直列呼び出しが支配的です。すべて並列に叩ける形なら、数ミリ秒から十数ミリ秒程度の上乗せに収まる構成が組めます。逆に@requiresが連鎖して3段、4段と直列になると、その回数ぶんネットワーク往復が積み上がる。導入前後の比較は平均値ではなくp95以降を見てください。
Federation 1で作ったサブグラフは2系にそのまま載せられますか?
多くの場合はそのまま載ります。Federation 2のコンポジションはFederation 1のサブグラフを受け付けるよう設計されており、段階移行が想定されています。ただし合成の検証は2系のほうが厳しく、1系では通っていたスキーマがエラーになる例もある。とくに2.15系ではコンポジションがRust実装へ置き換わった際に検証が強化されました。移行するなら、現行のサブグラフを2系のコンポジションに掛けてエラーの一覧を取るところから始めてください。
関連記事
- GraphQLとは?REST APIとの違い・メリット・デメリットをわかりやすく解説:フェデレーションの前提になるGraphQL自体の定義と特性
- GraphQLスキーマ設計の核心原則:合成の入力になるサブグラフのスキーマをどう設計するか
- Apollo Studioの全体像とGraphQL開発で果たす中核的役割:スキーマレジストリと変更履歴を見る側の運用
- GraphQL Code Generatorとは?client presetの設定とv7の変更点:スーパーグラフから型を生成するクライアント側の工程
- Apollo Clientとは?GraphQLクライアントの使い方とv4の変更点:ルーターの手前で動くクライアントとキャッシュの扱い