Estoy ejecutando el servidor Apollo lambda para GraphQL. Quiero interceptar la consulta / mutación GraphQL del cuerpo de la solicitud POST y analizarla para poder averiguar qué consulta / mutación está solicitando la solicitud. El entorno es Node.js.

La solicitud no es JSON, es el lenguaje de consulta GraphQL. He mirado alrededor para tratar de encontrar una manera de analizar esto en un objeto que pueda navegar pero estoy dibujando un espacio en blanco.

El servidor Apollo debe analizarlo de alguna manera para dirigir la solicitud. ¿Alguien conoce una biblioteca que haga esto o consejos sobre cómo puedo analizar la solicitud? Ejemplos de cuerpos de solicitud y lo que quiero recuperar a continuación.

{"query":"{\n  qQueryEndpoint {\n    id\n  }\n}","variables":null,"operationName":null}

Me gustaría identificar que esta es una consulta y que se está solicitando qQueryEndpoint.

{"query":"mutation {\\n  saveSomething {\\n    id\\n  }\\n}","variables":null}

Me gustaría identificar que se trata de una mutación y que se está utilizando la mutación saveSomething.

Mi primera idea para esto es eliminar los saltos de línea e intentar usar expresiones regulares para analizar la solicitud, pero parece una solución muy frágil.

14
Nick Ramsbottom 1 mar. 2018 a las 13:09

3 respuestas

La mejor respuesta

Puede usar 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);

Imprime:

operation query
name qQueryEndpoint

Y con tu mutación:

operation mutation
name saveSomething
14
Gabriel Bleu 1 mar. 2018 a las 11:14

Puede usar graphql-js así:

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
  }
});

Creo que esto es lo que las implementaciones de servidores GraphQL usan bajo el capó, podría estar equivocado.

0
brielov 18 abr. 2020 a las 12:18

graphql-tag se basa en la biblioteca central graphql (y, por lo tanto, la instala): si solo desea obtener el tipo de operación y el nombre, puede hacerlo utilizando {{X2} } directamente y analice el AST completo de la operación GraphQL analizada:

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)));

De esa manera, no necesita depender de graphql-tag y puede usar el AST GraphQL real (y, por lo tanto, adaptarse fácilmente a otros requisitos), porque graphql-tag no proporciona el AST completo.

Consulte la AST para la consulta en AST no Explorer.

3
Christian Ulbrich 26 nov. 2019 a las 16:24