Apollo Client中如何隔离GetNotesToApprove查询缓存不受其他查询影响?
解决方案:隔离两个查询的缓存数据
核心问题是GraphQL标准化缓存(比如Apollo Client这类库默认的缓存机制)会将相同ID的Note实体合并存储,导致GetNoteHistory仅请求部分字段后,缓存里的Note数据被覆盖,进而影响GetNotesToApprove的返回结果。以下是几种实用的隔离方案:
1. 给缓存加命名空间/拆分缓存实例
为两个查询的缓存数据添加专属前缀,或者直接创建独立的缓存实例,让GetNotesToApprove和GetNoteHistory的Note实体在缓存中完全隔离。
以Apollo Client为例:
// 为待审批笔记创建带前缀的缓存 const approveCache = new InMemoryCache({ dataIdFromObject: obj => `approve:${obj.id}` // 用前缀区分同ID的实体 }); // 为历史笔记创建另一个缓存 const historyCache = new InMemoryCache({ dataIdFromObject: obj => `history:${obj.id}` }); // 分别初始化客户端 const approveClient = new ApolloClient({ cache: approveCache, uri: '/graphql' }); const historyClient = new ApolloClient({ cache: historyCache, uri: '/graphql' });
2. 对GetNotesToApprove使用整响应缓存
禁用该查询的标准化缓存,直接缓存完整的响应结果,不拆解为单个实体。多数GraphQL客户端支持针对特定查询配置缓存策略:
// 查询待审批笔记时,强制缓存整个响应 const { data } = await approveClient.query({ query: GET_NOTES_TO_APPROVE, fetchPolicy: 'cache-first', context: { useResponseCache: true // 配合客户端的响应缓存配置,直接存储完整结果 } });
3. 拆分GraphQL Schema中的Note类型
从架构层面解决,将两个查询返回的类型拆分为EditableNote和HistoryNote,即使字段大部分重叠,也定义为独立类型。这样标准化缓存会将它们视为不同实体,不会互相覆盖。
Schema示例:
type EditableNote { id: ID! title: String! content: String! type: Int! author: String! # 包含编辑器需要的所有字段 } type HistoryNote { id: ID! title: String! type: Int! # 只保留历史列表需要的字段 } type Query { GetNotesToApprove: [EditableNote!]! GetNoteHistory: [HistoryNote!]! }
4. 强制GetNotesToApprove请求完整字段
确保该查询请求编辑器需要的所有字段(即使前端暂时不展示),让标准化缓存中的Note实体始终保留完整数据,避免被GetNoteHistory的部分字段覆盖。
查询示例:
query GetNotesToApprove { GetNotesToApprove { id title content type author createdAt # 列出编辑器依赖的所有字段 } }
内容的提问来源于stack exchange,提问作者mTv
相关产品推荐
相关产品推荐

