嵌套缓存的艺术:Apollo GraphQL 中文档存档状态更新
2024-03-04 11:14:00
维护 Apollo GraphQL 中嵌套缓存的艺术
问题陈述
我们有一个 Apollo GraphQL 查询,它获取文档列表并存储在一个嵌套的缓存对象中。该缓存对象包含两个集合:一个用于未存档的文档,另一个用于已存档的文档。为了保持缓存与服务器同步,我们需要找到一种方法来在文档存档状态更改时更新这两个集合。
解决方案:缓存更新
解决此问题的关键在于利用 Apollo GraphQL 的 cache.modify
方法。此方法允许我们使用更新函数修改缓存中的现有对象。
步骤详解
要修改嵌套缓存,请按照以下步骤操作:
-
获取用户对象标识符: 使用
cache.identify
方法获取要更新的用户对象的标识符。 -
创建更新函数: 使用
cache.modify
方法创建更新函数。这个函数将修改缓存中的用户对象。 -
更新嵌套集合: 在更新函数中,使用
fields
选项来更新documents
嵌套集合。对于每个集合,执行以下操作:- 存档文档: 从未存档的集合中移除文档,并将其添加到已存档的集合中。
- 取消存档文档: 从已存档的集合中移除文档,并将其添加到未存档的集合中。
-
应用缓存更新: 使用
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. 除了文档存档状态,我可以使用缓存更新更新哪些其他字段?
缓存更新可用于修改任何可修改的缓存字段,包括数组、对象和基本数据类型。