You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphQL Apollo分页与type policies配置 翻页结果追加缓存问题

配置错误点

  • 参数名拼写不一致:请求参数里的字段是includePartialMatch,但你在keyArgs中写的是includePartialMatches,多了末尾的s,直接导致参数匹配失效。
  • keyArgs逻辑遗漏:你需要让page、itemsToShow这两个分页参数不参与缓存key的生成,当前配置没有明确排除这两个字段,导致不同page的请求被判定为独立的缓存条目。
  • merge函数逻辑不完善:默认merge函数可接收第三个上下文参数args,你未接收该参数无法做分页相关的精细控制,同时现有合并逻辑未处理重复条目、分页元数据覆盖的边界情况。

修正后可用配置

const typePolicy = {
  // 仅用search下除page、itemsToShow之外的字段生成缓存key
  keyArgs: [
    "search",
    [
      "identifier",
      "searchTerm",
      "includePartialMatch", // 修正拼写与请求参数一致
      "filters",
      "orderBy",
      "facets",
    ],
  ],
  merge(existing, incoming, { args }) {
    // 首次请求无现有缓存直接返回新数据
    if (!existing) return { ...incoming };
    
    // 合并条目,基于id去重避免重复数据
    const itemMap = new Map(existing.items.map(item => [item.id, item]));
    incoming.items.forEach(item => itemMap.set(item.id, item));

    return {
      ...existing,
      ...incoming,
      items: Array.from(itemMap.values()),
      // 总数等元数据优先用最新接口返回的值
      total: incoming.total ?? existing.total
    };
  },
  // 可选配置:如果需要按请求参数返回对应页的数据,加上read函数,不需要可直接删除
  read(existing, { args }) {
    if (!existing) return undefined;
    const page = args?.search?.page ?? 1;
    const pageSize = args?.search?.itemsToShow ?? 10;
    const startIndex = (page - 1) * pageSize;
    return {
      ...existing,
      items: existing.items.slice(startIndex, startIndex + pageSize)
    };
  }
};

注意事项

  • 如果搜索返回的条目没有全局唯一的id字段,需要在InMemoryCache配置中给对应返回类型添加keyFields,避免缓存条目识别错误。
  • 如果不需要前端按分页参数切片返回对应页数据,直接删除read函数即可,Apollo会默认返回全部合并后的条目。

内容的提问来源于stack exchange,提问作者r3plica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 15:06:03