如何在Apollo Server中设置服务器端完整响应缓存

4
我试图根据这个指南为一项结果每天只更改一次的昂贵查询设置缓存。该查询需要7-8秒钟,大部分时间花在了DB查询上,因为从解析器返回的响应必须进行大量处理。
我使用的是apollo-server-express库和更改插件是apollo-server-plugin-response-cache
这就是我所做的:
server.js

const { ApolloServer } = require('apollo-server-express')
const responseCachePlugin = require('apollo-server-plugin-response-cache')

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: async ({ req }) => {
    // ...
  },
  plugins: [responseCachePlugin()]

resolvers.js

personDetails: async (root, args, ctx, info) => {
      info.cacheControl.setCacheHint({ maxAge: 600 })
      const persons = await Person.find({}).populate('details')

      // processing the data

      return processedData
}

我希望解析器只运行一次,之后响应应该几乎立即从缓存中返回。但这并没有实现。我是做错了什么还是没有理解应该如何工作呢。
我尝试在模式中也放置了缓存提示,但结果并没有改善。
2个回答

3
它应该可以正常运行。这里有一个可用的示例: server.ts:
import { ApolloServer, gql } from 'apollo-server-express';
import express from 'express';
import responseCachePlugin from 'apollo-server-plugin-response-cache';

const typeDefs = gql`
  type Query {
    personDetails: String
  }
`;
const resolvers = {
  Query: {
    personDetails: async (root, args, ctx, info) => {
      console.log(`[${new Date().toLocaleTimeString()}] Query.personDetails`);
      info.cacheControl.setCacheHint({ maxAge: 10 });
      return 'This is person details';
    },
  },
};

const app = express();
const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [responseCachePlugin()],
});

apolloServer.applyMiddleware({ app });

const server = app.listen({ port: 4000 }, () => {
  console.log(`The server is running in http://localhost:4000${apolloServer.graphqlPath}`);
});

请求日志:

The server is running in http://localhost:4000/graphql
[1:51:27 PM] Query.personDetails
[1:51:52 PM] Query.personDetails

响应头:
cache-control: max-age=10, public

第一个 graphql 请求在下午1点51分27秒发送。在接下来的10秒钟内,所有发送的请求都将命中缓存(默认为内存LRU缓存),这意味着graphql解析器personDetails将不会执行。graphql响应将从缓存中读取并发送到客户端。
10秒后,我在下午1点51分52秒发送另一个 graphql 请求。缓存已过期。因此,此请求将不会命中内存缓存。graphql解析器将执行并生成新值。
源代码:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/stackoverflow/57243105

2
抱歉在一年的沉默后重新提出这个问题。我目前处于同样的情况,而这段代码正好概括了我在我的代码中所做的事情。 我面临的问题是解析器的结果从未被放入缓存,因此解析器仍然在每个请求上执行。你知道可能是什么原因吗? - garritfra

0

我知道这是一个老问题,但它可能会帮助某人解决Apollo中的服务器端缓存问题。

据我所知,apollo-server-plugin-response-cache插件仅在基础REST API的响应具有control-cache头时才起作用。如果您的REST API中没有缓存控制头,则可以在restDataSouce GET调用中进行覆盖,如下所示。

return this.get(`uri_path`,"", {cacheOptions: { ttl: 1}});

接下来,按照问题片段中的示例,在解析器中继续使用info.cacheControl。maxAge将覆盖cacheOptions中提到的时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接