Apollo で複数の GraphQL エンドポイントに接続する(+ Shopify Storefront API)
はじめに
今回は自分の担当しているサービスで Shopify アプリケーションと連携する必要ができ Storefront API を使う事になりました。
弊社各サービスでは元々バックエンドとの通信に GraphQL を使っており、本記事の趣旨としては新しく Storefront API の GraphQL エンドポイントに接続するために調査した結果となります。
TR;DL
ApolloLink.split メソッドを使うと、もう一つ GraphQL エンドポイントを使うことができる
前提
GraphQL クライアントは Apollo となります。
また弊社フロントエンド環境(Next.js + TypeScript)での実装例になりますので、適宜読み替えてください。
要件としてシステム内のごく一部での連携のためこの方法を採用しておりますが、「普段から複数エンドポイントを使い分けている」「3つ以上のエンドポイントと連携する必要がある」場合には適用に際して再考の余地があるかと思われますのでご了承ください。
また Shopify Storefront API については必要最低限触れるのみで詳細な説明は省きます。参考とさせていただいたリンク先のブログ等をご参照ください。
準備
Shopify Storefront API のトークンを発行する
必要なアクセススコープ(権限)の設定を忘れずに行いましょう

動作確認
X-Shopify-Storefront-Access-Token ヘッダーに発行したアクセストークンを付与し、クエリを実行します。

権限に応じて欲しいデータが取得できていること、権限外のデータを取得する際はエラーになることが確認できます。

自分の作業環境では Altair GraphQL Client を愛用しています。
実装
Apollo クライアントを初期化する際に主要エンドポイントと連携用エンドポイントを定義し、 ApolloLink.split の第一引数に条件を指定します。
+ const primaryLink = new HttpLink({
+ uri: `${PRIMARY_API_URL}`,
+ });
+ const secondaryLink = new HttpLink({
+ uri: `${SECONDARY_API_URL}`,
+ headers: {
+ "X-Shopify-Storefront-Access-Token": SHOPIFY_STOREFRONT_TOKEN,
+ },
+ });
const client = new ApolloClient({
- link: new HttpLink({
- uri: `${API_URL}`,
- });
+ link: ApolloLink.split(
+ (operation) => operation.getContext().clientName === "secondary",
+ secondaryLink,
+ primaryLink
+ ),
});
呼び出す際には初期化時に指定した clientName を context オプションに指定します。
いつものエンドポイントを使う際にはコードに変更が起こらない点も良いですね。
- primaryLink
const { data, loading, error } = useXxxQuery();
- secondaryLink
const { data, loading, error } = useXxxQuery({ context: { clientName: "secondary" } });
上記サンプルコードは graphql-codegen の生成物を想定しています、適宜読み替えてください。
終わりに
今回は一部分だけの適用を想定して比較的変更量の少ない実装で対応をするつもりですが、この調査を通じて ApolloLink 周りのまだまだ知らないオプションがあったりしたので深堀りしていけたらと思います。
Discussion