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

31
我正在运行Apollo lambda服务器以处理GraphQL。我希望拦截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变异。

我最初的想法是去除换行符,并尝试使用正则表达式来解析请求,但感觉这是一个非常脆弱的解决方案。


我的问题错了。请求是GraphQL查询语言,而不是AST。我已经进行了编辑。感谢您的意见! - Nick Ramsbottom
1
https://www.npmjs.com/package/graphql-parser 的翻译内容为: - Gabriel Bleu
1
它解析查询字符串并返回一个对象,但是https://www.npmjs.com/package/graphql-tag似乎更受欢迎。 - Gabriel Bleu
我在考虑类似这样的代码:const query = gql\${body.query}`` - Gabriel Bleu
@GabrielBleu 哦,好的,我会在本地试一下并回报! - Nick Ramsbottom
显示剩余3条评论
4个回答

39
您可以使用 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

这太棒了!感谢您的帮助,我非常感激。 - Nick Ramsbottom
我们是否有类似的东西适用于Golang? - Deep Nirmal

28

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 Explorer中查看查询的AST。


3
你可以像这样使用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服务器实现在幕后使用的,尽管我可能错了。


0
您可以使用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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接