返回

嵌套缓存的艺术:Apollo GraphQL 中文档存档状态更新

javascript

维护 Apollo GraphQL 中嵌套缓存的艺术

问题陈述

我们有一个 Apollo GraphQL 查询,它获取文档列表并存储在一个嵌套的缓存对象中。该缓存对象包含两个集合:一个用于未存档的文档,另一个用于已存档的文档。为了保持缓存与服务器同步,我们需要找到一种方法来在文档存档状态更改时更新这两个集合。

解决方案:缓存更新

解决此问题的关键在于利用 Apollo GraphQL 的 cache.modify 方法。此方法允许我们使用更新函数修改缓存中的现有对象。

步骤详解

要修改嵌套缓存,请按照以下步骤操作:

  1. 获取用户对象标识符: 使用 cache.identify 方法获取要更新的用户对象的标识符。

  2. 创建更新函数: 使用 cache.modify 方法创建更新函数。这个函数将修改缓存中的用户对象。

  3. 更新嵌套集合: 在更新函数中,使用 fields 选项来更新 documents 嵌套集合。对于每个集合,执行以下操作:

    • 存档文档: 从未存档的集合中移除文档,并将其添加到已存档的集合中。
    • 取消存档文档: 从已存档的集合中移除文档,并将其添加到未存档的集合中。
  4. 应用缓存更新: 使用 cache.modify 方法应用缓存更新。

代码示例

const userId = 123; // 用户 ID
const archived = true; // 文档是否已存档

cache.modify({
  id: cache.identify({ __typename: "User", userId }),
  fields: {
    documents(documents) {
      const unarchivedDocuments = documents.filter((doc) => !doc.archived);
      const archivedDocuments = documents.filter((doc) => doc.archived);

      if (archived) {
        // 存档文档
        const doc = unarchivedDocuments.find((doc) => doc.id === documentId);
        if (doc) {
          unarchivedDocuments.splice(unarchivedDocuments.indexOf(doc), 1);
          archivedDocuments.push(doc);
        }
      } else {
        // 取消存档文档
        const doc = archivedDocuments.find((doc) => doc.id === documentId);
        if (doc) {
          archivedDocuments.splice(archivedDocuments.indexOf(doc), 1);
          unarchivedDocuments.push(doc);
        }
      }

      return [...unarchivedDocuments, ...archivedDocuments];
    },
  },
});

注意事项

  • 确保文档的唯一标识符在两个集合中相同。
  • 避免直接修改缓存对象。始终使用 cache.modify 方法。
  • 如果文档的存档状态发生变化,需要同时更新未存档和已存档集合。

结论

通过使用缓存更新,我们可以有效地维护 Apollo GraphQL 中的嵌套缓存。这使我们能够保持缓存与服务器同步,并根据应用程序的状态进行适当的更新。

常见问题解答

1. 为什么使用缓存更新?

缓存更新允许我们在不覆盖整个缓存对象的情况下修改其特定部分。这有助于提高性能并避免意外更改。

2. cache.identify 方法的作用是什么?

cache.identify 方法生成缓存对象中特定项目的唯一标识符。这对于访问和修改特定对象是必需的。

3. 如何确保文档的唯一标识符相同?

在文档模型中实现一个唯一的标识符字段,例如 id。确保在两个集合中使用相同的标识符。

4. 为什么需要同时更新未存档和已存档集合?

当存档状态更改时,文档需要从一个集合移动到另一个集合。如果不同时更新两个集合,缓存将处于不一致状态。

5. 除了文档存档状态,我可以使用缓存更新更新哪些其他字段?

缓存更新可用于修改任何可修改的缓存字段,包括数组、对象和基本数据类型。