为什么我们需要 `cacheRedirects`?

Why do we need `cacheRedirects` at all?

我阅读了 interacting with cached data and while I understand how cacheRedirects works, I'm a bit confused why it is needed in the first place. This is part of the reason why I asked this other question: 上的文档?

We know that the data is most likely already in the client cache, but because it's requested with a different query, Apollo Client doesn't know that.

这是为什么?

为清楚起见,复制粘贴文档中的示例:

query ListView {
  books {
    id
    title
    abstract
  }
}

query DetailView {
  book(id: $id) {
    id
    title
    abstract
  }
}

Apollo 以 normalized 方式缓存它接收到的数据。

如果您的 ListView return 数据如下:

{
  "data": {
    "books": [
      {
        "id": 1,
        "title" "ABC",
        "__typename": "Book"
      },
      {
        "id": 2,
        "title" "DEF",
        "__typename": "Book"
      }
    ]
  }
}

每本书将根据其 id__typenameBook:1Book:2 等)的键存储在缓存中。这个特定的缓存键列表然后与 books 根字段相关联。如果您再次请求 books,Apollo 会看到它已经在缓存中有该查询,并会根据键列表重新创建结果。

如果books接受一些参数,则每组参数都被视为不同的缓存条目。 books(onSale: true) 可能 return 一套不同于 books(subject: "Computer Science") 的书籍。每组缓存键都是单独存储的。如果您 运行 第一个查询然后是第二个,则第二个将是缓存未命中并且仍会命中服务器。

同样,您可以有一个带有一些参数的查询,并且 return 是一本书,例如 book(id: 1)。但是,在所有这些示例中,Apollo 并没有 "understand" 参数 idonSale 是什么。这些参数如何与 returned 结果相关是您业务逻辑的一部分。所有 Apollo "knows" 就是给定这个查询和这组参数,你得到这个特定的对象或对象数组。

作为一个人,我可以从命名中推断出像 book(id: 2) return 这样的查询是一本 ID 为 2 的书。但是像 Apollo 这样的库无法准确地推断出该信息——它如何猜测字段的正确类型或者它 return 是单个对象而不是对象数组?就此而言,它如何推断 id: 2 转换为 "Book where id = 2"?毕竟,实际的参数可以有多种形式:book(identifier: 2)book(filter: { id: 2 })

所以我们使用 cacheRedirects 来 "teach" Apollo 如何查找可能已经在我们缓存中的数据。这有效地复制了一些通常驻留在服务器上的业务逻辑,但帮助我们避免了对服务器的额外调用。