【问题标题】:Apollo GraphQL Server - Access query params from cache pluginApollo GraphQL Server - 从缓存插件访问查询参数
【发布时间】:2021-02-09 22:07:23
【问题描述】:

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

阿波罗服务器:

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

【问题讨论】:

    标签: node.js typescript graphql apollo-server


    【解决方案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 } } ]
    

    【讨论】:

    • 哇...好的,所以使用requestContext.document.definitions[0].selectionSet.selections[0].arguments 确实有效,谢谢!但是知道为什么requestContext.request.variables 仍然是空的吗?明确一点:第一条路径 确实 有我的论点,但 request.variables 不用于 same gql 调用。
    • 我在上面的问题中添加了我的解析器(以及您建议的更改)。我仍然没有在request.variables 中得到任何信息(但我可以使用你的 AST 建议)
    • @JordanKasper 也许我的回答不清楚。如果您想获得request.variables,您应该发送带有variables 的GraphQL 查询。检查此链接:graphql.org/learn/queries/#variables
    • 哦...我的错误,我现在明白这完全不同了。再次感谢。
    猜你喜欢
    • 2020-02-12
    • 2021-04-03
    • 2018-11-06
    • 1970-01-01
    • 2018-10-16
    • 2020-09-04
    • 1970-01-01
    • 2020-11-17
    • 2019-01-09
    相关资源
    最近更新 更多