阿波罗节点服务器;编写插件时如何在请求上下文中获取 mutation/query 模式路径?

Apollo nodejs server; How to get mutation/query schema path in the request context when writing a plugin?

我正在为 node.js 编写一个 Apollo 服务器插件,我的目标是改善我的团队调试体验。我的插件目前看起来像这样:

export function eddyApolloPlugin(): ApolloServerPlugin {
    return {
        requestDidStart(requestContext) {
            // Set requestId on the header
            const requestId = (requestContext?.context as EddyContext)?.requestId;
            if (requestId) {
                requestContext.response?.http?.headers.set('requestId', requestId);
            }
            return {
                willSendResponse(context) { // <== Where do I find the "path" in the schema here?
                    // Inspired by this: https://blog.sentry.io/2020/07/22/handling-graphql-errors-using-sentry
                    // and the official documentation here: https://docs.sentry.io/platforms/node/
                    // handle all errors
                    for (const error of requestContext?.errors || []) {
                        handleError(error, context);
                    }
                },
            };
        },
    };
}

我想知道我是否可以访问这里架构中的路径?使用 operation.operationName 很容易找到 mutaiton/query 的名称,但是我在哪里可以获得架构中定义的 query/mutation 的名称?

解决方案

export function eddyApolloPlugin(): ApolloServerPlugin {
    return {
        requestDidStart(requestContext) {
            // Set requestId on the header
            const requestId = (requestContext?.context as EddyContext)?.requestId;
            if (requestId) {
                requestContext.response?.http?.headers.set('requestId', requestId);
            }
            return {
                didResolveOperation(context) {
                    const operationDefinition = context.document
                        .definitions[0] as OperationDefinitionNode;
                    const fieldNode = operationDefinition?.selectionSet
                        .selections[0] as FieldNode;
                    const queryName = fieldNode?.name?.value;
                    // queryName is what I was looking for!
                },
            };
        },
    };
}

您的要求不是很明确。如果要获取 query/mutation 的名称以区分客户端发送的查询或突变。

您可以从 willSendResponse 事件处理程序中的 context.response.data 获取名称。

例如

server.ts:

import { ApolloServer, gql } from 'apollo-server';
import { ApolloServerPlugin } from 'apollo-server-plugin-base';
import { parse, OperationDefinitionNode, FieldNode } from 'graphql';

function eddyApolloPlugin(): ApolloServerPlugin {
  return {
    requestDidStart(requestContext) {
      return {
        didResolveOperation(context) {
          console.log('didResolveOperation');
          const obj = parse(context.request.query!);
          const operationDefinition = obj.definitions[0] as OperationDefinitionNode;
          const selection = operationDefinition.selectionSet.selections[0] as FieldNode;
          console.log('operationName: ', context.request.operationName);
          console.log(`${context.operation!.operation} name:`, selection.name.value);
        },
        willSendResponse(context) {
          console.log('willSendResponse');
          console.log('operationName: ', context.request.operationName);
          console.log(`${context.operation!.operation} name:`, Object.keys(context.response.data!)[0]);
        },
      };
    },
  };
}

const typeDefs = gql`
  type Query {
    hello: String
  }
  type Mutation {
    update: String
  }
`;
const resolvers = {
  Query: {
    hello() {
      return 'Hello, World!';
    },
  },
  Mutation: {
    update() {
      return 'success';
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers, plugins: [eddyApolloPlugin()] });
const port = 3000;
server.listen(port).then(({ url }) => console.log(`Server is ready at ${url}`));

GraphQL 查询:

query test {
  hello
}

服务器日志:

didResolveOperation
operationName:  test
query name: hello
willSendResponse
operationName:  test
query name: hello

GraphQL 突变:

mutation test {
  update
}

服务器日志:

didResolveOperation
operationName:  test
mutation name: update
willSendResponse
operationName:  test
mutation name: update