caching - 使用 Apollo 缓存具有多个 id 的 GraphQL 查询

标签 caching graphql apollo react-apollo apollo-client

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

我们有一个以 id 数组作为参数的查询,一个带有 id foo 的示例查询和 bar看起来像这样:

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 });
}

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

所以问题归结为:
当有一个查询缓存 routeNames: ["foo", "bar"] 的结果时稍后出现另一个查询,询问 routeNames: ["bar", "baz"] 的路线我们希望得到与 "bar" 对应的结果从缓存中发送查询 routeNames: ["baz"] .

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

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

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

最佳答案

一种想法是在进行实际查询之前检查本地缓存,并简单地将缓存中已经存在的 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

更新:或者您也可以设置 fetchPolicycache-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

关于caching - 使用 Apollo 缓存具有多个 id 的 GraphQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51637618/

相关文章:

Wordpress Varnish Age=0 或不缓存(Cookies?)

node.js - 在 EC2/Nodejs 后端 Redis/Varnish 中存储元数据和缓存 api 响应数据?

apollo - [网络错误] : Error: Error writing result to store for query Using Apollo Link State

android graphQL Apollo

javascript - 在从 apollo-boost 导出的 ApolloClient 中禁用缓存

c++ - 您可以在 C++ 中缓存虚函数查找吗?

ruby-on-rails-3 - Rails 用另一列覆盖 updated_at 以获得正确的 cache_key

javascript - Graphql - 有没有办法同时插入两个表,但第二个表依赖于从第一个表的返回?

graphql - Next js - 无法使用 apollo 客户端 api 生成动态 getStaticPaths

GatsbyJS 中的 GraphQL 过滤器