如何从Apollo InMemoryCache查询全部实体?缓存查询报错求助
解决Apollo InMemoryCache无参数查询全部实体的问题
我明白你遇到的问题了——带分页参数的entities查询能正常命中缓存,但无参数查询全部实体时,Apollo找不到对应的ROOT_QUERY.entities字段。这是因为带参数的查询在缓存中会被存储为带参数标识的键(比如entities({"limit":10,"offset":0})),而无参数查询直接找的是entities这个无参数键,缓存里根本没有这个条目。
要解决这个问题,确实需要通过InMemoryCache的cacheResolvers选项,为无参数的entities查询自定义缓存解析逻辑,从缓存中收集所有已存在的实体。下面是具体的实现方案:
步骤1:配置缓存解析器
在创建InMemoryCache时,为Query类型的entities字段添加解析函数,该函数不需要接收参数,直接从缓存中提取所有目标实体:
import { InMemoryCache, gql } from '@apollo/client'; const cache = new InMemoryCache({ cacheResolvers: { Query: { // 处理无参数的entities查询 entities: () => { // 步骤1:获取缓存中所有类型为"Entity"的实体键 // 缓存中单个实体的键格式为:`__typename:EntityId`,比如`Entity:123` const entityCacheKeys = Object.keys(cache.extract()).filter( key => key.startsWith('Entity:') ); // 步骤2:遍历键,读取每个实体的片段数据 return entityCacheKeys.map(key => cache.readFragment({ id: key, fragment: gql` fragment FullEntity on Entity { __typename EntityId // 这里可以添加你需要的其他实体字段 } ` }) ); } } } });
步骤2:确保无参数查询的结构匹配
你的无参数查询最好和带参数的查询保持字段一致(比如包含__typename),这样Apollo能正确匹配解析器返回的结果:
query LocalEntityList { entities { __typename EntityId // 其他需要的字段 } }
关键逻辑说明
- 我们通过
cache.extract()获取整个缓存的原始数据,筛选出所有属于Entity类型的实体键。 - 用
cache.readFragment()读取每个实体的指定字段,确保返回的结构和查询要求一致。 - 这种方式不依赖之前的分页查询缓存,只要实体被加载到过缓存中,就能被收集返回,比合并分页结果更可靠。
如果你的实体类型不是Entity,记得把代码中的Entity替换成你实际的__typename值。
内容的提问来源于stack exchange,提问作者Pierre-Alexandre
相关产品推荐
相关产品推荐

