阿波罗节点服务器;编写插件时如何在请求上下文中获取突变/查询模式路径?
Posted
技术标签:
【中文标题】阿波罗节点服务器;编写插件时如何在请求上下文中获取突变/查询模式路径?【英文标题】:Apollo nodejs server; How to get mutation/query schema path in the request context when writing a plugin? 【发布时间】:2021-01-17 22:54:03 【问题描述】:我正在为 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
很容易找到突变/查询的名称,但是我在哪里可以获得架构中定义的查询/突变的名称?
解决方案
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!
,
;
,
;
【问题讨论】:
【参考方案1】:您的要求不是很明确。如果您想获取查询/突变的名称以区分客户端发送的查询或突变。
您可以在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
【讨论】:
我想你理解我的问题 - 如果不清楚,抱歉。只需测试解决方案 - 2 分钟 :) 哦,等等 - 我在那里的扳机有点快。我感兴趣的是您上面示例中的查询名称。但我想在调用解析器之前得到这个。你知道这是否可能吗? 根据文档,我可以从didResolveOperation
获取 operationName --> 但是如何获取 queryName ?
@DauleDK 等等,让我检查一下。
由于查询是以字符串形式存在的,是否可以使用正则表达式提取查询名称?只需要检查命名和未命名的查询以上是关于阿波罗节点服务器;编写插件时如何在请求上下文中获取突变/查询模式路径?的主要内容,如果未能解决你的问题,请参考以下文章
使用阿波罗客户端上传图像时获取网络请求失败反应原生android