使用Apollo缓存具有多个ID的GraphQL查询

时间:2018-08-01 15:55:07

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

我们正在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。


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

当然,理想的情况是仅将"baz"作为我们方案中的缺失项。

1 个答案:

答案 0 :(得分:1)

一种想法是在进行实际查询之前检查本地缓存,然后只需从要查询的ID(routeNames)列表中删除缓存中已经存在的ID(routeNames)。

要在不接触网络的情况下检查缓存,请使用// Determine if there are any items checked. if(checkedListBox1.CheckedItems.Count != 0) { // If so, loop through all checked items and print results. string s = ""; for(int x = 0; x <= checkedListBox1.CheckedItems.Count - 1 ; x++) { s = s + "Checked Item " + (x+1).ToString() + " = " + checkedListBox1.CheckedItems[x].ToString() + "\n"; } MessageBox.Show (s); } readQuery()

文档在这里:

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

更新:或者,您也可以在查询选项中将readFragment()设置为fetchPolicy

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