首页 > 解决方案 > 使用缓存优先策略进行过度获取

问题描述

这是场景:

  1. 我通过使用 2 个变量(companyId:1 和 clientId:1)的查询查询发票列表,它返回 10 张发票。我使用 fetch-policy: cache-first
  2. 我为 (companyId:1, clientId:2) 创建了一个返回相应 Invoice 实体的新 Invoice。
  3. 我在第 1 步中重新发出查询 - 但我收到了 11 张发票。它包括为 clientId:2 创建的新发票。

我想问题是查询变量和缓存之间没有链接 - 所以它不可能工作。换句话说,我正在请求查询变量 {clientId:1} - 但缓存存储如下(即,不使用查询变量过滤器“clientId”。

Invoice:319
  id:"319"
  __typename:"Invoice"
 invoiceDate:"2021-05-25"
 invoiceAmount:650
 __ref:"Client:1"

不能以这种方式使用缓存吗?我是否需要在突变后重新获取,而不仅仅是返回 Invoice 实体数据?或者还有什么我可以做的吗?

这是返回发票(和其他实体)的第 1 步的查询:

query BillPay($companyId: ID!, $clientId: ID!) {
    client(options: { companyId: $companyId, clientId: $clientId }) {
      id
      displayName
    }
    payments(options: { companyId: $companyId, clientId: $clientId }) {
      id
      paymentDate
      paymentAmount
      reference
      client {
        id
      }
    }
    invoices(options: { companyId: $companyId, clientId: $clientId }) {
      id
      invoiceDate
      invoiceAmount
      client {
        id
      }
    }
  }

这是突变的反应

fragment InvoiceResponse on Invoice {
    id
    invoiceDate
    invoiceAmount
    client {
      id
      displayName
      colorNumber
    }
  }

标签: apollo-client

解决方案


答案是使用仅缓存获取策略的查询结果在突变后不可靠。更新缓存的突变将更新所有缓存的查询。这意味着您可能会根据查询变量获得不应包含的结果 - 因此您需要以编程方式过滤结果以确保您没有不需要的数据。

以下是我与 Apollo 团队的沟通:

从我:

好的。所以只是为了确认,如果我做了一个突变,我的带有变量的仅缓存查询可能包含基于变量不正确的数据 - 所以我需要过滤结果集以删除不正确的数据。我想知道这是否是常识。

从阿波罗出发:

更正您应该过滤结果集以删除不正确的数据。这不是常识,但它是团队在我们的文档中添加的良好反馈。


推荐阅读