Apollo服务器-关于缓存/数据源选项的困惑

时间:2018-11-18 06:27:24

标签: apollo apollo-client apollo-server apollostack

文档(https://www.apollographql.com/docs/apollo-server/features/data-sources.html#Using-Memcached-Redis-as-a-cache-storage-backend)显示如下代码:

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一样使用相同的高速缓存?

1 个答案:

答案 0 :(得分:4)

据我所知,传递给cache的{​​{1}}严格用于ApolloServer的上下文中。从REST端点获取资源时,服务器将检查响应上的RESTDataSource标头,如果存在,则将适当地缓存资源。这意味着,如果标头为Cache-Control,响应将以24小时的TTL进行缓存,并且在缓存条目到期之前,将使用该响应而不是调用相同的REST URL。

这与您已实现的缓存机制不同,因为您的代码缓存了来自数据库的响应。它们的意图是相同的,但是它们使用不同的资源。您的代码有效复制ApolloServer max-age=86400已经执行的操作的唯一方法是,如果您为REST端点编写了类似的cache

虽然这两个缓存都减少了处理GraphQL响应所需的时间(从缓存中获取的速度明显快于从数据库中获取的速度),但是客户端缓存减少了必须向服务器发出的请求的数量。最值得注意的是,DataSource使您可以跨站点中的不同位置(例如React中的不同组件)重用一个查询,而只提取一次查询。

由于客户端缓存已规范化,这还意味着如果通过一个查询获取资源时是否已经缓存了资源,则有可能避免在另一查询请求时重新获取资源。例如,如果您通过一个查询获取用户列表,然后通过另一个查询获取用户,则可以将客户端配置为在缓存中查找该用户,而不用进行第二次查询。

请务必注意,虽然缓存在服务器端的资源通常具有TTL,但InMemoryCache却没有。而是使用“提取策略”来确定单个查询的行为。例如,这使您可以从服务器中始终获取查询,无论缓存中有什么。

希望这有助于说明服务器端缓存和客户端缓存都是有用的,但方式却大不相同。