【发布时间】:2019-01-09 06:44:20
【问题描述】:
我们在 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 });
}
现在,当在客户端的多个位置使用查询时,我们希望仅获取未通过网络缓存的 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