Apollo Client 3.2.1 manager嵌套对象丢失:调优缓存策略无效
接口网络响应和Apollo返回对象字段不一致的排查方向
- 首先需要明确:
fetchPolicy: "network-only"仅代表客户端发起请求时优先从网络拉取最新数据,不会主动读取本地缓存的旧值,并不代表客户端会跳过响应返回后的缓存规范化逻辑。Apollo 3.x拿到网络响应后,默认会先对响应做实体化处理、写入缓存后,再从规范化后的缓存结构中提取当前查询需要的字段返回给组件,这步逻辑哪怕开了network-only也不会跳过,这是大多数人遇到这类问题的核心原因。 - 第一个可能诱因:
InMemoryCache的实体主键匹配规则引发的实体合并冲突- Apollo缓存默认会按照
__typename + 配置的keyFields把返回的对象识别成独立实体,如果你没有给Manager类型配置自定义的keyFields,默认会用_id作为主键。如果不同类型的实体(比如Order、Manager、甚至其他关联类型)碰巧存在相同的_id值,且当前版本的类型识别逻辑没有正确做区分,缓存会把这些不同来源的对象识别成同一个实体,把字段合并揉在一起,最终返回的嵌套manager对象就会出现字段缺失、值不对的情况 - 你当前配置中给
Locations设置了keyFields: [](即所有Locations实例都是同一个全局单例实体),这类全局类型的配置如果和其他嵌套类型存在关联,也可能意外触发跨类型的实体合并
- Apollo缓存默认会按照
- 第二个可能诱因:嵌套响应的
__typename字段缺失- Apollo识别实体类型完全依赖响应体中每个节点的
__typename字段,如果链路中存在响应加工逻辑(比如服务端返回后经过代理、自定义fetch中间件修改了响应体),把manager节点上的__typename字段删掉了,缓存层会无法正确识别manager对应的实体类型,从缓存中匹配到错误的实体返回。
- Apollo识别实体类型完全依赖响应体中每个节点的
- 第三个可能诱因:@apollo/client 3.2.1 版本的已知缺陷
- 你使用的
^3.2.1是Apollo Client 3.x的早期版本,存在多个和嵌套查询字段解析、实体规范化相关的已知bug,包括嵌套对象字段被错误裁剪、同主键实体跨类型合并等问题,这类问题在后续的3.3.0之后的版本中已经陆续修复。
- 你使用的
- 快速定位验证方法:
- 给httpLink加一个
afterware,在响应刚到达客户端、还未进入缓存规范化流程时打印原始响应体,和你最终从查询中拿到的返回值做对比。如果原始响应完全正确,就算改用原生XMLHttpRequest发起请求,问题也不会消失,因为冲突点不在网络传输环节,而在Apollo的响应解析环节 - 临时移除所有自定义的typePolicies配置,重新发起查询对比结果
- 临时将缓存配置替换为
new InMemoryCache(),完全去掉自定义类型规则,验证问题是否消失
- 给httpLink加一个
内容的提问来源于stack exchange,提问作者Simon Pasku
相关产品推荐
相关产品推荐

