Apollo Client のキャッシュの仕組みメモ
Apolloクライアントのキャッシュの仕組みをメモがてらに記載しています。
Apollo Client のキャッシュの概要
Apollo クライアントは、GraphQLクエリの結果を正規化してローカルのメモリ内に保存します。このメモリ内のクエリ結果をキャッシュとして利用します。
GraphQLクエリの実行時にクエリ結果がキャッシュ(メモリ内)にある場合は、ネットワークリクエストを省略して即時に応答することでパフォーマンス向上ができます。
公式ドキュメントのシーケンス図を引用しつつ、具体例を説明します。
GetBook(bookId: "5")
のGraphQLクエリを実行するケースを考えてみましょう。
「Apollo Client」の初回のGetBook(bookId: "5")
のGraphQLクエリ実行時は「InMemoryCache」にBook:5
のデータが存在しないため、「GraphQL Server」にクエリを実行して結果を取得します。そして、クエリ結果を「InMemoryCache」に正規化して保存し、「Apollo Client」にクエリ結果を返します。
その後、2回目以降のGetBook(bookId: "5")
のGraphQLクエリを実行時は、「InMemoryCache」にBook:5
のデータが存在するため、「GraphQL Server」にネットワークリクエストを実施せず、そのままキャッシュの値を「Apollo Client」に返します。
このように、キャッシュを使うことで、アプリケーションは即時に応答することができます。
しかし、キャッシュを使うことでメモリとサーバーの状態がずれてバグの温床にもなり得るので注意が必要です。
サポートされているFetch Policy
Apollo Client でサポートされているフェッチポリシーは次の6つになります。キャッシュの挙動に影響を与えるため、どのポリシーを使っているかを理解することが大切です。
ポリシー名 | 説明 |
---|---|
| ネットワークリクエストの数を最小限に抑えることを優先している。 |
| 高速な応答を提供しつつ、サーバーとローカルデータの一貫性を維持できる。 |
| サーバーとローカルデータの一貫性を常に保てる。 |
| サーバーとローカルデータの一貫性を常に保つが、キャッシュは更新しない。 |
| キャッシュに全てのフィールドのデータがあれば返す。なければ、エラーをスローする。 |
|
|
Fetch Policyの設定方法
フェッチポリシーの設定方法は、主に次の2つがあります。
new ApolloClient
時にfetchPolicy
を指定useQuery
でfetchPolicy
を指定
「new ApolloClient
時にfetchPolicy
を指定」するとデフォルトのフェッチポリシーを指定することができます。(参考: class Apollo Client)
const client = new ApolloClient({
uri: 'https://flyby-router-demo.herokuapp.com/',
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: 'cache-first',
},
watchQuery: {
fetchPolicy: 'cache-and-network'
},
},
});
また、「useQuery
でfetchPolicy
を指定」すると、個別でフェッチポリシーを指定できます。
const { loading, error, data } = useQuery(GET_TODOS, {
fetchPolicy: 'network-only', // キャッシュを利用せずGraphQLサーバーに常にリクエスト。クエリ結果はキャッシュする
});
Apollo Client のキャッシュを可視化する
ブラウザ拡張の Apollo Client Devtools を利用することで、キャッシュを可視化できます。
Apollo Clientのキャッシュの仕組み
キャッシュはメモリに正規化されて格納されます。
また、キャッシュのIDはデフォルトでは __typename
と id
(もしくは _id
)フィールドを使います。
詳細を知りたい場合は、How is data stored? で確認できます。
Apollo Client のキャッシュを操作する
Apollo Client のキャッシュを直接操作することができます。
メソッド | 説明 |
---|---|
| GraphQLのクエリ結果を取得・変更できる |
| フラグメントの値を取得・変更できる |
| キャッシュの値を直接変更できる |
より詳細は Reading and writing data to the cacheを参照ください。