我阅读了interacting with cached data上的文档,虽然我了解了cacheRedirects
的工作原理,但我有点困惑为什么首先需要它。这是我问另一个问题Does the Apollo client cache nested objects in React的部分原因。
我们知道数据很可能已经在客户端缓存中,但是由于它是通过不同的查询请求的,因此Apollo Client不知道。
那是为什么?
为清楚起见,将示例粘贴到文档中
query ListView {
books {
id
title
abstract
}
}
query DetailView {
book(id: $id) {
id
title
abstract
}
}
答案 0 :(得分:2)
Apollo以normalized的方式缓存接收到的数据。
如果您的ListView
返回的数据如下:
{
"data": {
"books": [
{
"id": 1,
"title" "ABC",
"__typename": "Book"
},
{
"id": 2,
"title" "DEF",
"__typename": "Book"
}
]
}
}
每本书将基于id
和__typename
(Book:1
,Book:2
等)的密钥存储在缓存中。然后,该特定的缓存键列表与books
根字段关联。如果再次请求books
,则Apollo将看到它已经在缓存中具有该查询,并将根据键列表重新创建结果。
如果books
接受一些参数,则每组参数将被视为不同的缓存条目。 books(onSale: true)
可能返回的书集与books(subject: "Computer Science")
不同。每组高速缓存键分别存储。如果您先运行第一个查询,然后再运行第二个查询,则第二个将是缓存未命中,并且仍然会命中服务器。
类似地,您可以进行一个查询,该查询接受一些参数并返回一本书,例如book(id: 1)
。但是,在所有这些示例中,Apollo都不“了解”参数id
和onSale
是什么。这些参数如何与返回的结果相关联是您的业务逻辑的一部分。所有Apollo“知道”的就是给定该查询和这组参数,您将获得该特定对象或对象数组。
作为人类,我可以从命名中推断出类似book(id: 2)
之类的查询会返回一本ID为2
的书。但是,像Apollo这样的库无法准确地推断出该信息-它如何猜测字段的正确类型或如何返回单个对象而不是对象数组?因此,如何推断id: 2
转换为“其中id = 2的书”?毕竟,实际参数可能有多种方式:book(identifier: 2)
,book(filter: { id: 2 })
等。
因此,我们使用cacheRedirects
“教导”阿波罗如何查找可能已经在缓存中的数据。这有效地复制了通常驻留在服务器上的一些业务逻辑,但有助于我们避免对服务器的额外调用。