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

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

问题描述

文档(

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.moviesAPI.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.显然,在dataSource实现中使用了RedisCache,但是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天全站免登陆