How to parse GraphQL request string into an object

后端 未结 3 1373
轮回少年
轮回少年 2021-02-19 09:02

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

相关标签:
3条回答
  • 2021-02-19 09:41

    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.

    0 讨论(0)
  • 2021-02-19 09:45

    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.

    0 讨论(0)
  • 2021-02-19 09:57

    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
    
    0 讨论(0)
提交回复
热议问题