Apollo Client のキャッシュ正規化

Published: 2023/7/22


Apollo Client は、 GraphQL サーバーからの特に Query のレスポンスを、ライブラリが内部で持っているキャッシュ機構に、レスポンスのデータを正規化しながら格納する。

Apollo Client は、レスポンスのデータ中にネストされた(json)オブジェクトを発見するたび、データの正規化を試みる。 データの正規化は、 Cache ID が生成できる場合にのみ適用される。 デフォルトの typePolicy (apollo キャッシュの設定ポリシー) では、オブジェクトが __typename と、 id もしくは _id のフィールドを持つ場合において、 ${__typename}:${id} 形式で Cache ID を生成する。 Cache ID が生成できず、正規化ができない場合には、ネストしたオブジェクトを持った親オブジェクトをそのままキャッシュに投入する。

キャッシュによる正規化が行われると、そのオブジェクトは { "__ref": cacheId } の値によって置換される。 キャッシュ全体は巨大な json オブジェクトで、 Cache ID をキーとして、各正規化されたオブジェクトを保持する。 根本の Query 自身は、 ROOT_QUERY というキーで保持される。

{
  "ROOT_QUERY": {
    "__typename": "Query",
    "tasks": [
      { "__ref": "Task:1" },
      { "__ref": "Task:2" }
    ]
  },
  "Task:1": {
    "__typename": "Task",
    "id": 1,
    "name": "Pay bill",
    "finished": false
  },
  "Task:2": {
    "__typename": "Task",
    "id": 2,
    "name": "Go Gym",
    "finished": false
  }
}

なお、このようにキャッシュ内部では、オブジェクトは正規化されて保持されるが、 useQuery などにてキャッシュからデータが読み出される場合には、元々の、非正規化された状態でデータは読み出される。

カスタマイゼーション

キャッシュに対する設定を行うことにより、いろいろカスタマイズできる。


Tags: graphqlapollo-client