🍉

Apollo Client で複数エンドポイントを扱う方法

2022/10/28に公開

Linc'wellに転職して半年とちょっと、GraphQLの良さに感動しつつ、つまずきつつフロントエンド開発を楽しんでいます。
これまではApollo Clientで自社のエンドポイントのみを扱っていたのですが、一部外部のエンドポイントへのアクセスが必要になりました。最小限の変更だけでシンプルに出し分けしたいけどどうすれば良いんだっけ?となったので記事に残しておきます。

各エンドポイントの設定

まずは、メインで使っているエンドポイントとサブのエンドポイントの設定を行います。

import { HttpLink } from '@apollo/client';

const primaryLink = new HttpLink({
  uri: 'https://xxxprimary.com/graphql',
  // options
});

const secondaryLink = new HttpLink({
  uri: 'https://xxxsecondary.com/graphql',
  // options
});

エンドポイントの使い分け条件を設定

以下の様にsplitメソッドの第一引数に条件を設定します。条件がtrueの場合は第二引数が、falseの場合は第三引数が使われます。これによってprimaryLinkを使う場合は今まで通りの呼び出し方のままで問題なく、secondaryLinkを使いたい場合だけ引数を渡す形で呼び出すことができます。

import { ApolloClient, ApolloLink } from '@apollo/client';

const client = new ApolloClient({
  link: ApolloLink.split(
    // contextに clientName: 'secondary'が含まれている場合は、secondaryLinkを使う。それ以外はprimaryLinkを使う
    (operation) => operation.getContext()['clientName'] === 'secondary',
    secondaryLink,
    primaryLink
   )
});

https://www.apollographql.com/docs/react/api/link/introduction/#directional-composition
ドキュメントによると他にも以下のような用途があるとのことで、なかなか汎用性が高そうです。

  • 操作の種類に応じて、許可される再試行回数をカスタマイズする
  • 操作の種類に応じて異なるトランスポートメソッドを使用する(クエリーは HTTP、サブスクリプションは WebSocket など)
  • ユーザーがログインしているかどうかに応じてロジックをカスタマイズする

Queryの実行

これまで通りの呼び出しで変更の必要はなしです。

useQuery(query, { variables });
useQuery(query, { variables, context: { clientName: 'secondary' }});

おわりに

今回は変更を少なく複数エンドポイントを扱うためにこのような対応をしました。しかしprimaryLinkとsecondaryLinkを同じくらい使う場合や、3つ以上のエンドポイントを扱う場合は運用辛そうだなと思います。そういう場合はやはりSchema stitchingなどを使うのが良いのかも知れません。
ただ、他のエンドポイントを少しだけ使いたい場合は今回の対応は選択の一つとしてありだと思いました。

GitHubで編集を提案
Linc'well, inc.

Discussion