【问题标题】:How to parse GraphQL request string into an object如何将 GraphQL 请求字符串解析为对象
【发布时间】:2018-08-09 09:03:49
【问题描述】:

我正在为 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 突变。

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

【问题讨论】:

标签: javascript node.js graphql apollo-server


【解决方案1】:

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

【讨论】:

  • 这太棒了!谢谢你帮助我,我很感激。
  • 我们有类似 golang 的东西吗?
【解决方案2】:

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 服务器实现在后台使用的,不过我可能会弄错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      相关资源
      最近更新 更多