我正在运行 GraphQL 的 Apollo lambda 服务器。我想从 POST 请求正文中截获 GraphQL 查询/突变并解析它,以便我可以找到请求请求的查询/突变。环境是节点.js。
请求不是 JSON,而是 GraphQL 查询语言。我环顾四周,试图找到一种方法将其解析为我可以导航的对象,但我正在绘制一个空白。
Apollo 服务器必须以某种方式解析它以引导请求。有谁知道一个库可以做到这一点或关于我如何解析请求的指针?请求正文的示例以及我想在下面检索的内容。
{"query":"{n qQueryEndpoint {n idn }n}","variables":null,"operationName":null}
我想确定这是一个查询,并且正在请求qQueryEndpoint
。
{"query":"mutation {\n saveSomething {\n id\n }\n}","variables":null}
我想确定这是一个突变,并且正在使用saveSomething
突变。
我的第一个想法是去掉换行符并尝试使用正则表达式来解析请求,但这感觉是一个非常脆弱的解决方案。
你可以使用 graphql-tag :
const gql = require('graphql-tag');
const query = `
{
qQueryEndpoint {
id
}
}
`;
const obj = gql`
${query}
`;
console.log('operation', obj.definitions[0].operation);
console.log('name', obj.definitions[0].selectionSet.selections[0].name.value);
打印输出 :
operation query
name qQueryEndpoint
而你的突变:
operation mutation
name saveSomething
graphql-tag
构建在核心graphql
库之上(因此可以安装它) - 如果你只想获取操作的类型和名称,你可以这样做,直接使用graphql
并分析解析的 GraphQL 操作的完整 AST:
const { parse } = require('graphql');
const query = `
{
qQueryEndpoint {
id
}
}
`;
const mutation = `
mutation {
saveSomething {
id
}
}
`;
const firstOperationDefinition = (ast) => ast.definitions[0];
const firstFieldValueNameFromOperation = (operationDefinition) => operationDefinition.selectionSet.selections[0].name.value;
const parsedQuery = parse(query);
const parsedMutation = parse(mutation);
console.log('operation', firstOperationDefinition(parsedQuery).operation);
console.log('firstFieldName', firstFieldValueNameFromOperation(firstOperationDefinition(parsedQuery)));
console.log('operation', firstOperationDefinition(parsedMutation).operation);
console.log('firstFieldName', firstFieldValueNameFromOperation(firstOperationDefinition(parsedMutation)));
这样你就不需要依赖graphql-tag
,你可以使用真正的GraphQL AST(因此很容易适应进一步的需求) - 因为graphql-tag
不提供完整的 AST。
请参阅 AST 资源管理器中的查询的 AST。
你可以像这样使用graphql-js
:
const { parse, visit } = require('graphql');
const query = `
{
books {
...rest of the query
}
}
`
const ast = parse(query);
const newAst = visit(ast, {
enter(node, key, parent, path, ancestors) {
// do some work
},
leave(node, key, parent, path, ancestors) {
// do some more work
}
});
我相信这就是 graphql 服务器实现在引擎盖下使用的,不过我可能弄错了。
您可以使用graphql-tag
.
const gql = require('graphql-tag');
const query = `
{
qQueryEndpoint {
id
}
}
`;
const obj = gql`
${query}
`;
console.log('operation', obj.definitions[0].operation);
console.log('operationName', obj.definitions[0].name.value);