问题描述
我正在为GraphQl运行Apollo Lambda服务器.我想从邮政请求正文中拦截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突变.
我的第一个想法是剥离线路断裂并尝试使用正则表达式来解析请求,但感觉就像是一个非常脆弱的解决方案.
推荐答案
您可以使用 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是在Core 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)));
这样,您就不需要依赖graphql-tag,并且可以使用 real graphql ast(因此很容易适应其他要求) - 因为graphql-tag不提供完整的要求ast.
请参阅其他推荐答案 您可以使用graphql-js so: 我相信这是GraphQl Server实现在引擎盖下使用的,但是我可能会误会.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
}
});
问题描述
I am running Apollo lambda server for GraphQL. I want to intercept the GraphQL query/mutation from the POST request body and parse it so I can find out which query/mutation the request is asking for. The environment is Node.js.
The request isn't JSON, it's GraphQL query language. I've looked around to try and find a way to parse this into an object that I can navigate but I'm drawing a blank.
The Apollo server must be parsing it somehow to direct the request. Does anyone know a library that will do this or pointers on how I can parse the request? Examples of request bodies and what I want to retrieve below.
{"query":"{\n qQueryEndpoint {\n id\n }\n}","variables":null,"operationName":null}
I would like to identify that this is a query and that qQueryEndpoint is being asked for.
{"query":"mutation {\\n saveSomething {\\n id\\n }\\n}","variables":null}
I would like to identify that this is a mutation and the saveSomething mutation is being used.
My first idea for this is to strip out the line breaks and try and use regular expressions to parse the request but it feels like a very brittle solution.
推荐答案
You can use 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);
Prints out :
operation query name qQueryEndpoint
And with your mutation :
operation mutation name saveSomething
其他推荐答案
graphql-tag is built upon the core graphql library (and thus installs it along) - if you just want to get the type of operation and the name of it you can do so, by using graphql directly and analyze the full AST of the parsed GraphQL operation:
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)));
That way you do not need to depend on graphql-tag and you can use, the real GraphQL AST (and thus easily adapt to further requirements) - because graphql-tag does not provide the full AST.
See the AST for the query in AST Explorer.
其他推荐答案
You could use graphql-js like so:
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 } });
I belive this is what graphql server implementations uses under the hood, I could be mistaken though.