Apollo Federation 2 へ移行(統一)しました
こんにちは、介護/障害福祉事業者向け経営支援サービス「カイポケ」のリニューアルプロジェクトで介護サービスの提供を管理する機能の開発を担当している李です。3ヶ月前ぐらいに弊社の Advent Calendar 2024 シリーズ2の12/24の記事として「GraphQL Federation(Apollo Federation) の subgraph 運用時の落とし穴とその対策」を投稿しました。その時に弊社の Apollo Federation の利用について少し疑問を持つところがありました。その後精査したところ、Apollo Federation 1 と Apollo Federation 2 を併用していることが分かり、Apollo Federation 2 へ移行する取り組みをして統一できるようにしました。
問題発見
弊社は Apollo Federation を使う時に下記の仕組みとなっています。
- gateway + composition method + subgraph
この中に、gateway と composition method はバージョンを明記していて Federation 2 になっていることが分かります(詳細な判断方法は移行資料をご参考)。それに対して、subgraph のバージョンを明記せずどんなバージョンを使っているか分かりませんが、gateway と composition method と同じく Federation 2 になっているじゃないかと勝手に想像しました。
しかし、冒頭で言ったように「GraphQL Federation(Apollo Federation) の subgraph 運用時の落とし穴とその対策」を投稿する時に気づいたのは、Apollo Federation 2 の記述方法に関する資料に記載している Subgraph の書き方を採用していないこと(※)が分かりました。
Gateway や Subgraph Compose 仕組みと異なっているので現在のシステムで使っているのは Apollo Federation 1 かそれとも Apollo Federation 2 か疑問を持つようになりました。
※例:Apollo Federation 2 の Composition Rules に下記の情報を明記していて、複数の subgraph は同名の type を使う時に @shareable
を使わないいといけないですが、弊社の実装はそうなっていないです(例:type Query { _empty: Boolean }
を複数 subgraph に存在しているが、@shareable
を使っていない)。
-
Multiple subgraphs can't define the same field on an object type, unless that field is shareable.
また、上記の通り弊社の実装では Apollo Federation 2 の subgraph の書き方を採用していないですが、 Apollo Federation 2 の directive (@inaccessible)を使っているのでなぜ使えるか疑問を持つようになりました
仮説
- 現状 Apollo Federation の運用は V1・V2 両方が混ざっている中途半端の状態である
- Apollo Federation 2 で本来の directive の使い方ではなく何か特別な使い方を使っている
検証
仮説1についての検証
Apollo Federation 1とApollo Federation 2 の関係を調べたところ、Apollo Federation 1 から Apollo Federation 2 へ移行する手順が見つかりました。その手順を確認して仮説1の内容が判明できました。つまり、現在のシステムでは移行手順の3ステップのうちステップ1とステップ2(Gateway&Compose仕組み)ができているが、ステップ3(Subgraph)ができていないため(ただし、後方互換性があるため動作は問題なし)
仮説2についての検証
仮説1と同様にApollo Federation 1 から Apollo Federation 2 へ移行する手順によると「custom directive」を定義できるため、Apollo Federation 2 で本来の directive の使い方ではなく「custom directive」をつかっていることを判明できました
-
If your library doesn't support Federation 2 directives yet, you can still use that library with Federation 2 if the library lets you add custom directive definitions to your schema!
対策
基本的に Apollo Federation 1 から Apollo Federation 2 へ移行する手順の通りで実施して対応できました。ただし、subgraph の記載方法を Apollo Federation 2 へ移行すると同時に開発環境に対して下記 2 点追加対応も必要です:
-
Linter のバージョンアップ
- Apollo Federation 2 をサポートするために @graphql-eslint/eslint-plugin を 4.3.0 以上に設定
- この対応をしないと、Apollo Federation 2 以降に追加した directive がエラーになります
-
開発 IDE プラグインの設定
- 設定しないと directive を識別できないエラーが表示されます。弊社は IntelliJ を使っているため、Apollo's JetBrains Plugin を利用します。
- 詳細な設定下記を参考ください:
-
上記の設定をしないと Apollo Federation 2 以降に追加した directive はコンパイルエラーが発生します
考察
まず今回の対応によって、下記の2つの改善を実現できました
- Apollo Federation 2 へ統一することによって認識の混乱を無くしました。そうすることで認識のばらつきによって不正な Apollo Federation の使い方を早期に回避できるためシステムの不具合のリスクを減らせました
- Apollo Federation の directive の使い方も本来の使い方になり、不正な directive 定義を回避してシステムの不具合のリスクを減らせました
あと、今後 Apollo Federation を活用するハードルを下げました
- Apollo Federation はバージョンによって subgraph の書き方が変わります。現状使っている Apollo Federation のバージョンが分からないため、どの書き方で良いのか判断が難しいです。そのため、Apollo Federation 2 の機能を活用するハードルが高いです。また使いたい directive をすべて自分で定義しているため、バージョン管理や定義方法が難しいです
- 今回の対応によって上記の問題を解決して今後 Apollo Federation をより活用できるようになりました
最後に、Apollo Federation は運用で graphql スキーマ以外に開発環境の Lint / IntelliJ の Plugin などとセットで使うため、全部問題なく使うのは複雑度がやや高いです。今回の対応によってこれらの知識を網羅できたため全体の認知負荷を下げました
Discussion