【问题标题】:Why do we need `cacheRedirects` at all?为什么我们需要`cacheRedirects`?
【发布时间】:2020-03-09 17:02:06
【问题描述】:

我阅读了interacting with cached data 上的文档,虽然我了解cacheRedirects 的工作原理,但我有点困惑为什么首先需要它。这就是我问另一个问题的部分原因:Does the Apollo client cache nested objects in React?

我们知道数据很可能已经在客户端缓存中,但因为它是通过不同的查询请求的,所以 Apollo 客户端不知道。

这是为什么呢?

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

query ListView {
  books {
    id
    title
    abstract
  }
}

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

【问题讨论】:

    标签: graphql apollo apollo-client apollo-cache-inmemory


    【解决方案1】:

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

    如果您的ListView 返回如下数据:

    {
      "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) 可能会返回与books(subject: "Computer Science") 不同的书籍集。每组缓存键都是单独存储的。如果您运行第一个查询然后第二个,第二个将是缓存未命中,仍然会命中服务器。

    同样,您可以有一个带有一些参数并返回一本书的查询,例如book(id: 1)。然而,在所有这些例子中,Apollo 并不“理解”idonSale 的参数是什么。这些参数与返回结果的关系是您业务逻辑的一部分。所有 Apollo “知道”的是,给定这个查询和这组参数,你会得到这个特定的对象或对象数组。

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

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

    【讨论】:

      猜你喜欢
      • 2019-06-09
      • 2014-06-18
      • 2017-02-26
      • 2011-04-03
      • 2017-07-27
      • 2020-09-21
      • 2018-12-24
      • 2012-04-08
      • 1970-01-01
      相关资源
      最近更新 更多