GraphQL Federation
#GraphQL
概要
複数のマイクロサービスのGraphQLスキーマを統合するためのアーキテクチャパターン
「どのように分散したGraphQLサービスを統合するか」の設計思想
Apollo社が2019年にApollo Federation仕様という標準仕様を策定した
Federation仕様を実際に実行する具体的なソフトウェアコンポーネントについてはGraphQL Gateway技術一覧参照
GraphQL Federation概念の誕生背景
code:text
2012年: Facebook内でGraphQL開発開始
↓
2015年: GraphQL仕様オープンソース化
↓
2016-2018年: マイクロサービス普及とGraphQLエコシステム成熟
↓
2019年: Apollo Federation仕様策定(概念の具体化)
↓
2019年以降: 他社による代替実装登場(概念の拡散)
概念
Federated Schema(連合スキーマ)
各マイクロサービスが独自のサブグラフを定義し、Gateway層でそれらを自動的に統合してスーパーグラフ
GraphQL Federationにおけるスキーマ設計手法全体を指す抽象的な概念
複数のサブグラフを連合させてひとつの統合されたAPIを提供するアーキテクチャパターンの総称
「連合されたスキーマ」という考え方や設計思想そのもの
Supergraph
統合された最終的なGraphQLスキーマ
Schema Compositionプロセスを経て実際に生成された、統合済みの具体的なGraphQLスキーマ
クライアントが実際にクエリを送信する対象となる物理的なスキーマファイル
Subgraph
各マイクロサービスが提供する個別のGraphQLスキーマ
Entity(エンティティ)
複数のサービス間で共有されるオブジェクト型
@keyディレクティブで一意識別子を指定し、サービス間でのオブジェクト参照を可能にする
Reference Resolution(参照解決)
あるサービスのエンティティが他のサービスのフィールドを必要とする場合、Gatewayが自動的に適切なサービスに追加クエリを送信してデータを解決
Schema Composition
複数のサブグラフを統合してスーパーグラフを作成するプロセス
Schema Registry
スキーマを中央管理するレジストリ(Apollo Studioなど)
https://gyazo.com/c8a2b5035a8a83102741ad7d2ce3c062
GraphQL Federationはどのように動かしますか? - Money Forward Developers Blog
アーキテクチャ構成
Gateway層
Apollo Gateway / Apollo Router: 最も一般的な実装
Schema Composition: 各サブグラフのスキーマを統合
Query Planning: クライアントクエリを複数のサブグラフクエリに分解
Query Execution: 適切な順序でサブグラフを呼び出し
Response Merging: 各サービスからのレスポンスを統合
サブグラフ(各マイクロサービス)
独自のGraphQLスキーマとリゾルバー
@key、@external、@requires、@providesなどの連合ディレクティブ
他のサービスのエンティティを参照可能
連合ディレクティブ
@key: エンティティの一意識別子を定義
@extends: 他のサービスで定義されたエンティティを拡張
@external: 他のサービスで定義されたフィールドを参照
@requires: フィールド解決に必要な外部フィールドを指定
@provides: このサービスが提供できる外部フィールドを宣言
技術的メリット
開発者体験
型安全性: 統合されたスキーマによる強力な型チェック
自動的な関連解決: 複雑なサービス間の関連を透明に処理
単一エンドポイント: クライアントから見ると1つのAPIとして動作
アーキテクチャ利点
独立開発: 各チームが独自にスキーマを進化させられる
段階的移行: 既存のRESTサービスから段階的に移行可能
スキーマ検証: Gateway層でスキーマの整合性を自動検証
苦手なこと
プロダクト横断での検索やソート
Federation は「既存のサブグラフを組み合わせて“単一スキーマに見せる”」のが強みですが、横断的な全文検索・ソート処理を分散クエリで実現するのは非効率になりがちです。
例えば「社員名で全文検索+各プロダクトの属性でソート」といったケースでは、各サブグラフにクエリを投げて集めた結果をゲートウェイ側で後処理する必要があり、パフォーマンスが悪化します
プロダクト横断での集約
集計(COUNT, SUM, AVGなど)は通常 DB の得意分野ですが、Federation ではサブグラフごとに計算 → ゲートウェイでマージする流れになります。
つまり「売上を部門横断で集計」みたいな処理は、Federation が直接最適化できるわけではなく、集約用の専用サブグラフや BFF を別途用意した方が現実的です。
横断したデータをページネーション
ページネーションは通常「一意にソート可能な集合」に対して効率的に動きます。
Federationで複数サブグラフから「社員リストを統合してページネーション」とすると、
各サブグラフからデータを取り寄せ
ゲートウェイで結合・ソート・ページング
という流れになり、データ件数が多いほど重く非効率になります。Relay風の@cursor付きページネーションをそのまま横断に使うのは難しいです。
技術的課題と解決策
パフォーマンス課題
N+1 問題: DataLoaderパターンで解決
クエリ複雑度制限: Gateway レベルでクエリ深度とコストを制限
スキーマ進化管理
Schema Registry: Apollo Studio での中央集権的スキーマ管理
バージョニング戦略: Additive Changes(追加的変更)を推奨
実装における考慮点
認証・認可
サブグラフレベルでの細かい認可制御が可能です。フィールドレベルでのアクセス制御を実装できます。
エラーハンドリング
部分失敗への対応として、フォールバック処理を実装します。
監視・観測性
分散トレーシングの実装により、複数サービス間のクエリ実行を追跡できます。
適用判断基準
適している場面
複数チームでマイクロサービス開発
データ間の関連が複雑
GraphQLの型安全性を活用したい
段階的なAPIモダナイゼーション
適していない場面
単純なCRUD操作が中心
チーム規模が小さい(5人未満)
パフォーマンスが最重要
GraphQLの学習コストを避けたい
参照
Apollo Docs - Apollo GraphQL Docs