Apollo GraphQL Server-从缓存插件访问查询参数

时间:2020-10-27 15:26:20

标签: node.js typescript graphql apollo-server

我有一个使用apollo-server-plugin-response-cache插件的Apollo GraphQL服务器,我需要根据传入参数确定是否要写入缓存。我已经设置了插件,并且正在使用shouldWriteToCache挂钩。我可以打印出传递到挂钩中的GraphQLRequestContext对象,并且可以看到完整的请求源,但是request.variables为空。除了解析query本身之外,如何在此挂钩中访问解析器的实际参数? (在下面的示例中,我需要值为param2。)

Apollo服务器:

new ApolloServer({
    introspection: true,
    playground: true,
    subscriptions: false,
    typeDefs,
    resolvers,
    cacheControl: {
        defaultMaxAge: 60
    },
    plugins: [
        apolloServerPluginResponseCache({
            cache,  // This is a "apollo-server-cache-redis" instance
            shouldWriteToCache: (requestContext) => {
                
                // I get a lot of info here, including the source query, but not the 
                // parsed out query variables
                console.log(requestContext.request);
                
                // What I want to do here is:
                return !context.request.variables.param2
                // but `variables` is empty, and I can't see that value parsed anywhere else
            }
        })
    ]
})

这是我的解析器:

export async function exapi(variables, context) {
  // in here I use context.param1 and context.param2
  // ...
}

我也尝试过:

export async function exapi(variables, { param1, param2 }) {
  // ...
}

这是我从上面的代码中注销的内容:

{
  query: '{\n' +
    '  exapi(param1: "value1", param2: true) {\n' +
    '    records\n' +
    '  }\n' +
    '}\n',
  operationName: null,
  variables: {},            // <-- this is empty?! How can I get param2's value??
  extensions: undefined,
  http: Request {
    size: 0,
    timeout: 0,
    follow: 20,
    compress: true,
    counter: 0,
    agent: undefined,
    [Symbol(Body internals)]: { body: null, disturbed: false, error: null },
    [Symbol(Request internals)]: {
      method: 'POST',
      redirect: 'follow',
      headers: [Headers],
      parsedURL: [Url],
      signal: null
    }
  }
}

1 个答案:

答案 0 :(得分:1)

  1. 如果不为GraphQL查询提供variables,则可以通过AST的ArgumentNode从GraphQL查询字符串中获取参数

  2. 如果为GraphQL查询提供variables,则将从requestContext.request.variables获取。

例如

server.js

import apolloServerPluginResponseCache from 'apollo-server-plugin-response-cache';
import { ApolloServer, gql } from 'apollo-server';
import { RedisCache } from 'apollo-server-cache-redis';

const typeDefs = gql`
  type Query {
    exapi(param1: String, param2: Boolean): String
  }
`;
const resolvers = {
  Query: {
    exapi: (_, { param1, param2 }) => 'teresa teng',
  },
};

const cache = new RedisCache({ host: 'localhost', port: 6379 });

const server = new ApolloServer({
  introspection: true,
  playground: true,
  subscriptions: false,
  typeDefs,
  resolvers,
  cacheControl: {
    defaultMaxAge: 60,
  },
  plugins: [
    apolloServerPluginResponseCache({
      cache,
      shouldWriteToCache: (requestContext) => {
        console.log(requestContext.document.definitions[0].selectionSet.selections[0].arguments);
        return true;
      },
    }),
  ],
});
server.listen().then(({ url }) => console.log(`? Server ready at ${url}`));

GraphQL查询:

query{
  exapi(param1: "value1", param2: true) 
}

服务器日志打印param1param2参数:

? Server ready at http://localhost:4000/
[]
[ { kind: 'Argument',
    name: { kind: 'Name', value: 'param1', loc: [Object] },
    value:
     { kind: 'StringValue',
       value: 'value1',
       block: false,
       loc: [Object] },
    loc: { start: 15, end: 31 } },
  { kind: 'Argument',
    name: { kind: 'Name', value: 'param2', loc: [Object] },
    value: { kind: 'BooleanValue', value: true, loc: [Object] },
    loc: { start: 33, end: 45 } } ]