GraphQL federationについて調べたことをまとめる。
GraphQL Federationは、複数のGraphQLサービスを統合するための方法である。
GraphQLのマイクロサービスのようなもので、単一のGraphQLエンドポイントとして複数のGraphQLサービスを利用することができるようにするアーキテクチャパターンである。
各ドメインごとのGraphQLサービスをSubgraphと呼ぶ。
GraphQLスキーマとリゾルバが定義される。
Subgraphを統合するGraphQLサービスをGatewayと呼ぶ。
各Subgraphのスキーマを統合することで、1つのGraphQLエンドポイントとしてクライアントに提供する。
クライアントからのGraphQLクエリを解析し、適切なSubgraphにリクエストを転送する。
複数のSubgraphのスキーマを統合することをSchema compositionと呼ぶ。
SubgraphごとにGraphQLサービスを分割することで、モジュール性が向上し、各サービスごとに独立して開発・デプロイが可能になる
Gatewayを通じて複数のSubgraphを統合することで、クライアントは1つのGraphQLエンドポイントからデータを取得できるため、スキーマの単一化が実現される。
Gatewayがクエリを解析し、適切なSubgraphにリクエストを転送することで、クエリの最適化が可能になる。
SubgraphごとにGraphQLサービスを分割することで、APIの進化が柔軟になる。
Gatewayが複数のSubgraphを統合するため、データ依存関係が複雑になる。
また、クエリのネストが深くなることで、複数のサブグラフにまたがるリゾルバが発生し、パフォーマンスが低下する可能性がある。
Gatewayが複数のSubgraphを統合するため、Gatewayがダウンすると全てのSubgraphにアクセスできなくなる。
Subgraphごとのスキーマ管理やGatewayの運用管理が必要になるため、運用負荷が増加する。
両者のアーキテクチャは似ている点があるが、異なる点も多い。
異なる点 | GraphQL Federation | マイクロサービス |
---|---|---|
提供するインターフェース | 統一されたGraphQLインターフェースを提供。クライアントは1つのGraphQLエンドポイントを使用。 | 複数のAPI(REST、gRPCなど)を提供。クライアントはサービスごとに異なるAPIエンドポイントを呼び出す。 |
統合方法 | サブグラフ間でGraphQLスキーマを統合。クライアントに一貫したGraphQL APIを提供。 | サービス間の統合はAPI呼び出しやメッセージング、イベント駆動型アプローチによる。 |
スキーマの分割方法 | 各サブグラフは独自のGraphQLスキーマを持ち、@key や@requires などで他のサブグラフとデータを統合。 |
各サービスは独自のスキーマ(データベース、API)を持ち、API経由でデータを提供。 |
結合の粒度 | サブグラフ間の結合は主にクエリ単位で行われ、サービス間の統合はGraphQLスキーマで管理される。 | サービス間の結合はAPI呼び出しやメッセージングを通じて行われ、複雑な場合がある。 |
クライアント視点 | クライアントは1つのGraphQLエンドポイントを通じて、複数のサービスからデータを取得できる。 | クライアントは複数のAPIエンドポイントを直接呼び出す必要があり、サービス間の違いを意識する。 |
状態管理 | サーバー側で状態管理を行い、スキーマやリゾルバでデータの一貫性を保つ。 | 各サービスが自身のデータベースを持ち、イベント駆動やCQRSを使用してサービス間の整合性を保つ。 |
サブグラフ間の依存関係管理 | サブグラフ間でスキーマの依存関係を明示的に定義し、@requires や@key を使用して依存関係を管理。 |
サービス間の依存関係はAPI呼び出しやイベント駆動型のアプローチで管理されるが、サービス間で調整が必要な場合が多い。 |
リファクタリング | スキーマの変更が主にGraphQLスキーマ内で行われるが、サブグラフ間の依存関係が増えると管理が複雑になることがある。 | サービス単位で独立してリファクタリングが行えるが、サービス間の統合部分で問題が発生すると調整が必要になる。 |
組織体制 | サービスごとにチームが分かれているが、スキーマ全体の管理が必要。各チームは自分のサブグラフに集中する。 | 各サービスごとに専任のチームが必要で、サービス間の調整が組織内でのコラボレーションに依存する。 |
スケーラビリティ | サービスが増えるたびにGraphQLサーバーがサブグラフと統合するが、統一されたエンドポイントを通じてスケールが可能。 | 各サービスは独立してスケーリングが可能だが、統合部分でのオーバーヘッドが発生する可能性がある。 |
誤解を恐れず端的にいうと、クライアント側が楽でバックエンド側が楽ではないのがGraphQL Federation、その逆がマイクロサービスといえるかもしれない。
サービス間の結合がどこで解決されるかによって、その負担がどこに依るか左右される。
GraphQL federationの方が、マイクロサービスよりも疎結合度合いが低く、Subgraph間の依存関係を意識する必要性があるため、チーム間の連携が求められる可能性がありそう。
依存関係の観点で違いをまとめてみた。
比較点 | GraphQL Federation | マイクロサービス |
---|---|---|
チーム間の調整頻度 | 高い(スキーマ変更や依存関係の調整が頻繁に必要) | 中程度(API契約やイベント駆動の調整が必要だが、独立性が高い) |
変更の影響範囲 | サブグラフ間の結合が強いため、変更の影響が他のチームにも波及しやすい | 各サービスが独立しているため、影響範囲を小さくできる(ただしAPI契約の管理は必要) |
リリースの独立性 | 低い(統合スキーマを保つため、各チームのリリースを調整する必要がある) | 高い(バージョニングやイベント駆動で各サービスを独立してデプロイ可能) |
依存関係の調整 | 高い(サブグラフ同士の関係性が強く、影響範囲が広がりやすい) | 低い(疎結合を保ちやすいが、APIの変更時には調整が必要) |
複数のSubgraph間のトランザクションはどうやって管理するのだろうか? GraphQLの責務ではなさそうだが、Federationで何か仕組みとか設計パターンがあったりするのだろうか。