Apollo Server - 关于缓存/数据源选项的困惑 [英] Apollo Server - Confusion about cache/datasource options

查看:39
本文介绍了Apollo Server - 关于缓存/数据源选项的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The docs (https://www.apollographql.com/docs/apollo-server/features/data-sources.html#Using-Memcached-Redis-as-a-cache-storage-backend) show code like this:

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.movi​​esAPI.someFunc().例如,假设我想为 SQL 数据库实现自己的缓存.看起来像

I was wondering how that cache key is used, considering it seems like the caching is actually custom implemented in something like MoviesAPI() and then used via context.dataSources.moviesAPI.someFunc(). For example, say I wanted to implement my own cache for a SQL database. It'd look like

  cache: new RedisCache({
    host: 'redis-server',
  }),
  dataSources: () => ({
    SQL: new SQLCache(),
  }),
});

其中 SQLCache 有我自己的连接到 RedisCache 的函数,例如:

where SQLCache has my own function that connects to the RedisCache like:

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

所以这意味着我在 ApolloServer cache 键和 dataSource 实现中都有 RedisCache.很明显,RedisCache 是在 dataSource 实现中使用的,但是 ApolloServer cache 键到底做了什么?

So that means I have RedisCache in both the ApolloServer cache key and dataSource implementation. Clearly, the RedisCache is used in the dataSource implementation, but then what does that ApolloServer cache key do exactly?

同样在客户端,示例主要展示了使用 InMemoryCache 而不是 Redis 缓存.客户端 Apollo 缓存应该是与服务器缓存不同的缓存还是应该像 RedisCache 这样的缓存在两个地方?

Also on the client, examples mostly show use of InMemoryCache instead of Redis cache. Should the client Apollo cache be a different cache from the server cache or should the same cache like RedisCache be in both places?

推荐答案

传递给 ApolloServercache 是,据我所知,严格用于RESTDataSource.当从 REST 端点获取资源时,服务器将检查响应中的 Cache-Control 标头,如果存在,将适当地缓存资源.这意味着如果标头是 max-age=86400,响应将被缓存 24 小时的 TTL,并且直到缓存条目过期,它将被使用而不是调用相同的 REST url.

The cache passed to the ApolloServer is, to my knowledge, strictly used in the context of a RESTDataSource. When fetching resources from the REST endpoint, the server will examine the Cache-Control header on the response, and if one exists, will cache the resource appropriately. That means if the header is max-age=86400, the response will be cached with a TTL of 24 hours, and until the cache entry expires, it will be used instead of calling the same REST url.

这与您实现的缓存机制不同,因为您的代码会缓存来自数据库的响应.他们的意图是相同的,但他们使用不同的资源.您的代码可以有效复制 ApolloServer 的 cache 已经做的事情的唯一方法是,如果您为 REST 端点编写了类似的 DataSource.

This is different than the caching mechanism you've implemented, since your code caches the response from the database. Their intent is the same, but they work with different resources. The only way your code would effectively duplicate what ApolloServer's cache already does is if you had written a similar DataSource for a REST endpoint instead.

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

While both of these caches reduce the time it takes to process your GraphQL response (fetching from cache is noticeably faster than from the database), client-side caching reduces the number of requests that have to be made to your server. Most notably, the InMemoryCache lets you reuse one query across different places in your site (like different components in React) while only fetching the query once.

因为客户端缓存是规范化的,这也意味着如果通过一个查询获取资源时已经缓存了资源,您可以避免在另一个查询请求时重新获取它.例如,如果您使用一个查询获取用户列表,然后使用另一个查询获取用户,则您的客户端可以配置为在缓存中查找用户,而不是进行第二个查询.

Because the client-side cache is normalized, it also means if a resource is already cached when fetched through one query, you can potentially avoid refetching it when it's requested with another query. For example, if you fetch a list of Users with one query and then fetch a user with another query, your client can be configured to look for the user in the cache instead of making the second query.

需要注意的是,虽然服务器端缓存的资源通常具有 TTL,但 InMemoryCache 没有.相反,它使用获取策略"来确定单个查询的行为.例如,这让您可以始终从服务器获取查询,而不管缓存中有什么.

It's important to note that while resources cached server-side typically have a TTL, the InMemoryCache does not. Instead, it uses "fetch policies" to determine the behavior of individual queries. This lets you, for example, have a query that always fetches from the server, regardless of what's in the cache.

希望这有助于说明服务器端和客户端缓存都很有用,但方式却截然不同.

Hopefully that helps to illustrate that both server-side and client-side caching are useful but in very different ways.

这篇关于Apollo Server - 关于缓存/数据源选项的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆