【问题标题】:Cache GraphQL query with multiple ids using Apollo使用 Apollo 缓存具有多个 id 的 GraphQL 查询
【发布时间】:2019-01-09 06:44:20
【问题描述】:

我们在 Web 应用程序中使用 apollo 客户端,并正在寻找提高缓存使用率的方法。

我们有一个以 id 数组作为参数的查询,id 为 foobar 的示例查询如下所示:

query routes {
  routes(routeNames: ["foo", "bar"]) {
    items {
      name
      route
      defaults
    }
  }
}

缓存设置如下所示:

export const cacheRedirects = {
  Query: {
    routes: (_: any, args: RoutesArgs, { getCacheKey }: Resolver<'name'>): Array<CacheKey> =>
      args.routeNames.map(name => getCacheKey({ __typename: 'Route', name })),
  },
};

export const dataIdFromObject = (object: QueryResult): ?string => {
  switch (object.__typename) {
    case 'Route':
      return `${object.__typename}:${object.name}`;
    default: return defaultDataIdFromObject(object);
  }
};

export function newCache(): InMemoryCache {
  return new InMemoryCache({ dataIdFromObject, cacheRedirects });
}

现在,当在客户端的多个位置使用查询时,我们希望仅获取未通过网络缓存的 routeName 的数据,并通过缓存检索其余数据。

所以问题归结为: 当有一个查询缓存routeNames: ["foo", "bar"] 的结果,然后另一个查询请求routeNames: ["bar", "baz"] 的路由时,我们希望从缓存中获取对应于"bar" 的结果并发送一个routeNames: ["baz"] 的查询。

我不确定 Apollo 是否以及如何做到这一点,因为与 cacheRedirect example 相比,这里我们处理多个 id 而不是单个。


现在,如果我们不能缓存每个数组项,那么我们可以做的下一个最好的事情是将 id 转换为公共缓存键,以便 ["foo", "bar"]["bar", "foo"] 最终使用相同的缓存键,但 @987654332 @ 会使用不同的。

当然,理想的做法是仅获取 "baz" 作为我们场景中的缺失项。

【问题讨论】:

  • 好问题!你最终得到了什么?
  • 谢谢 :) - 我在大约 3 年前做了一个项目,用于重写查询的 apollo-link,但在 2018 年 8 月的某个时候失去了对它的关注。所以有些事情开始了,但从未完成,我相信 Apollo从那以后大幅重组了他们的代码库 - 所以我不希望我之前的任何代码处于有用状态。出于实际目的,我认为它已成为两件事的结合:架构的某些部分现在更容易缓存/使用,而对于其他部分,我们目前并不关心。

标签: caching graphql apollo react-apollo apollo-client


【解决方案1】:

一个想法是在进行实际查询之前检查本地缓存,然后简单地将缓存中已经存在的 ID (routeNames) 从 ID (routeNames) 列表中删除以进行查询。

要在不接触网络的情况下检查缓存,请使用readQuery()readFragment()

文档在这里:

https://www.apollographql.com/docs/react/advanced/caching.html#readquery https://www.apollographql.com/docs/react/advanced/caching.html#readfragment

更新:或者,您也可以在查询选项中将 fetchPolicy 设置为 cache-only

https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-options-fetchPolicy

更新 2:集成检查以便它们为每个查询运行的一种好方法可能是自定义客户端中间件,该中间件将在调用服务器之前在每个请求上运行。

https://www.apollographql.com/docs/react/advanced/network-layer.html#linkMiddleware

【讨论】:

  • 嘿,谢谢 - 我们将研究中间件方法。我会相应地接受;)
猜你喜欢
  • 2020-10-18
  • 2021-06-17
  • 2018-06-13
  • 2020-02-12
  • 2021-08-14
  • 2016-12-12
  • 2021-11-14
  • 2020-02-05
  • 2021-12-06
相关资源
最近更新 更多