我正在为GraphQL运行Apollo lambda服务器。我想拦截来自POST请求体的GraphQL查询/变异并解析它,以便我可以找出请求要求的查询/变异。环境是Node.js。
请求不是JSON,而是GraphQL查询语言。我环顾四周试图找到一种方法将其解析成一个我可以导航的对象,但我正在画一个空白。
Apollo服务器必须以某种方式解析它以指导请求。有没有人知道这样做的库或指向我如何解析请求的指针?请求正文的示例以及我想在下面检索的内容。
{"query":"{\n qQueryEndpoint {\n id\n }\n}","variables":null,"operationName":null}
我想确定这是一个查询,并要求qQueryEndpoint
。
{"query":"mutation {\\n saveSomething {\\n id\\n }\\n}","variables":null}
我想确定这是一个突变并且正在使用saveSomething
突变。
我的第一个想法是删除换行符并尝试使用正则表达式来解析请求,但这感觉就像一个非常脆弱的解决方案。
答案 0 :(得分:7)
您可以使用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
答案 1 :(得分:2)
graphql-tag
建立在核心graphql
库的基础上(并随之安装)-如果您只想获取操作的类型和名称,可以使用{ {1}}并分析已解析的GraphQL操作的完整AST:
graphql
这样,您就不必依赖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)));
并可以使用 real GraphQL AST(因此可以轻松地适应进一步的要求)-因为graphql-tag
可以没有提供完整的AST。
在AST Explorer中查询查询的AST。
答案 2 :(得分:1)
您可以像这样使用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服务器实现的幕后手段,您可能会误会。