GraphQL federationについて

システムアーキテクチャ

GraphQL federationについて調べたことをまとめる。

GraphQL Federationとは

GraphQL Federationは、複数のGraphQLサービスを統合するための方法である。

GraphQLのマイクロサービスのようなもので、単一のGraphQLエンドポイントとして複数のGraphQLサービスを利用することができるようにするアーキテクチャパターンである。

GraphQL federationのアーキテクチャ

Subgraph

各ドメインごとのGraphQLサービスをSubgraphと呼ぶ。

GraphQLスキーマとリゾルバが定義される。

Gateway

Subgraphを統合するGraphQLサービスをGatewayと呼ぶ。

各Subgraphのスキーマを統合することで、1つのGraphQLエンドポイントとしてクライアントに提供する。

クライアントからのGraphQLクエリを解析し、適切なSubgraphにリクエストを転送する。

Schema composition

複数のSubgraphのスキーマを統合することをSchema compositionと呼ぶ。

GraphQL Federationのメリット・デメリット

メリット

モジュール性とスケーラビリティ

SubgraphごとにGraphQLサービスを分割することで、モジュール性が向上し、各サービスごとに独立して開発・デプロイが可能になる

スキーマの単一化

Gatewayを通じて複数のSubgraphを統合することで、クライアントは1つのGraphQLエンドポイントからデータを取得できるため、スキーマの単一化が実現される。

パフォーマンスの最適化

Gatewayがクエリを解析し、適切なSubgraphにリクエストを転送することで、クエリの最適化が可能になる。

APIの進化に柔軟

SubgraphごとにGraphQLサービスを分割することで、APIの進化が柔軟になる。

デメリット

複雑なオーケストレーション

Gatewayが複数のSubgraphを統合するため、データ依存関係が複雑になる。

また、クエリのネストが深くなることで、複数のサブグラフにまたがるリゾルバが発生し、パフォーマンスが低下する可能性がある。

Gatewayの単一障害点

Gatewayが複数のSubgraphを統合するため、Gatewayがダウンすると全てのSubgraphにアクセスできなくなる。

運用負荷の増加

Subgraphごとのスキーマ管理やGatewayの運用管理が必要になるため、運用負荷が増加する。

GraphQL federationとマイクロサービスの異なる点

両者のアーキテクチャは似ている点があるが、異なる点も多い。

異なる点 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で何か仕組みとか設計パターンがあったりするのだろうか。

参考