如何将 GraphQL 请求字符串解析为对象



我正在运行 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);

最新更新