const { RedisCache } = require('apollo-server-cache-redis');
const server = new ApolloServer({
typeDefs,
resolvers,
cache: new RedisCache({
host: 'redis-server',
// Options are passed through to the Redis client
}),
dataSources: () => ({
moviesAPI: new MoviesAPI(),
}),
});
我想知道如何使用cache
键,因为考虑到缓存实际上是在MoviesAPI()
之类的东西上定制实现的,然后通过context.dataSources.moviesAPI.someFunc()
使用。例如,假设我想为SQL数据库实现自己的缓存。看起来像
cache: new RedisCache({
host: 'redis-server',
}),
dataSources: () => ({
SQL: new SQLCache(),
}),
});
其中SQLCache
具有我自己的功能,该功能可以像这样连接到RedisCache
:
getCached(id, query, ttl) {
const cacheKey = `sqlcache:${id}`;
return redisCache.get(cacheKey).then(entry => {
if (entry) {
console.log('CACHE HIT!');
return Promise.resolve(JSON.parse(entry));
}
console.log('CACHE MISS!');
return query.then(rows => {
if (rows) redisCache.set(cacheKey, JSON.stringify(rows), ttl);
return Promise.resolve(rows);
});
});
}
因此,这意味着我在RedisCache
ApolloServer
键和cache
实现中都拥有dataSource
。显然,在RedisCache
实现中使用了dataSource
,但是ApolloServer
cache
键到底能做什么呢?
在客户端上,示例也大部分显示使用InMemoryCache
而不是Redis缓存。客户端Apollo高速缓存应该与服务器高速缓存不同,还是应该像RedisCache
一样使用相同的高速缓存?
答案 0 :(得分:4)
据我所知,传递给cache
的{{1}}严格用于ApolloServer
的上下文中。从REST端点获取资源时,服务器将检查响应上的RESTDataSource
标头,如果存在,则将适当地缓存资源。这意味着,如果标头为Cache-Control
,响应将以24小时的TTL进行缓存,并且在缓存条目到期之前,将使用该响应而不是调用相同的REST URL。
这与您已实现的缓存机制不同,因为您的代码缓存了来自数据库的响应。它们的意图是相同的,但是它们使用不同的资源。您的代码有效复制ApolloServer max-age=86400
已经执行的操作的唯一方法是,如果您为REST端点编写了类似的cache
。
虽然这两个缓存都减少了处理GraphQL响应所需的时间(从缓存中获取的速度明显快于从数据库中获取的速度),但是客户端缓存减少了必须向服务器发出的请求的数量。最值得注意的是,DataSource
使您可以跨站点中的不同位置(例如React中的不同组件)重用一个查询,而只提取一次查询。
由于客户端缓存已规范化,这还意味着如果通过一个查询获取资源时是否已经缓存了资源,则有可能避免在另一查询请求时重新获取资源。例如,如果您通过一个查询获取用户列表,然后通过另一个查询获取用户,则可以将客户端配置为在缓存中查找该用户,而不用进行第二次查询。
请务必注意,虽然缓存在服务器端的资源通常具有TTL,但InMemoryCache
却没有。而是使用“提取策略”来确定单个查询的行为。例如,这使您可以从服务器中始终获取查询,无论缓存中有什么。
希望这有助于说明服务器端缓存和客户端缓存都是有用的,但方式却大不相同。