5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Apollo ClientのキャッシュでInterfaceやUnionを利用する (WARNING: heuristic fragment matching going on!)

Posted at

Apollo Clientのキャッシュ機能は便利で特に設定をせずにそのまま使えてたのですが、UnionやInterfaceを利用する際に工夫が必要だったのでご紹介します。

問題

Apollo ClientでUnionやInterfaceを含んだクエリを扱うと以下のようなWarningが出ました。

Image1.png

これはFragment MatcherというApollo Clientのキャッシュ機構に使われているもので、デフォルトのものだとInterfaceやUnionには対応できないため警告がでています。

これを解決するためにはサーバーで定義されたスキーマに対応したFragment Matcherを用意する必要があります。

解決策

Fragment Matcherの設定を行うにはまず、GraphQL Code Generatorというツールを使います。

@graphql-codegen/cli@graphql-codegen/fragment-matcher のインストールが必要です。

 yarn add -D @graphql-codegen/cli @graphql-codegen/fragment-matcher

次にGraphQL Code Generatorの設定ファイルを用意します。


# codegen.yml
schema: [YOUR_API]
overwrite: true
generates:
  ./fragmentTypes.json:
    plugins:
      - fragment-matcher

このような設定になります。schema オプションにGraphQLサーバーのエンドポイント、またはスキーマ情報が書かれたjsonファイルなどが入ると思います。

設定が完了したら、以下コマンドを実行してください。

$ yarn run gql-gen
#or
$ npm run gql-gen

実行後、fragmentTypes.jsonというファイルが生成されます。

これはGraphQLのスキーマ情報であるIntrospection Resultを自動で出力されたものです。

例えば

union Animal
    = Dog | Cat | Bear

のようなスキーマが定義されていたとすると、fragmentTypes.jsonは以下のようなものが出力されるはずです。

{
  "__schema": {
    "types": [
      {
        "kind": "UNION",
        "name": "Animal",
        "possibleTypes": [
          {
            "name": "Dog"
          },
          {
            "name": "Cat"
          },
          {
            "name": "Bear"
          }
        ]
      }
    ]
  }
}

あとはこの生成されたfragmentTypes.jsonをApollo Clientインスタンス作成時に読み込むことでWarningを解消することができます。

import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import introspectionQueryResultData from '../fragmentTypes.json'

// IntrospectionFragmentMatcher
const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
})
// InMemoryCache
const cache = new InMemoryCache({ fragmentMatcher })

const apolloClient = new ApolloClient({
  cache,
  ...省略
})

最後に

今回はGraphQL Code Generatorを利用してIntrospection Resultを出力しましたが、手動でスクリプトを書いてサーバーからのレスポンスで出力する方法もありますので、ドキュメントを参考にしてみてください。

ドキュメント: Using fragments

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?