web-dev-qa-db-fra.com

Enregistrer la requête et les variables GraphQL apollo-server par requête

Lorsque vous utilisez apollo-server 2.2.1 ou une version ultérieure, comment peut-on enregistrer, pour chaque requête, la requête et les variables?

Cela semble être une exigence simple et un cas d'utilisation courant, mais la documentation est très vague , et l'objet query passé à formatResponseplus = a les propriétés queryString et variables.

8
Dan Dascalescu

La réponse d'Amit fonctionne (aujourd'hui), mais à mon humble avis, c'est un peu hacky et cela peut ne pas fonctionner comme prévu à l'avenir, ou cela peut ne pas fonctionner correctement dans certains scénarios.

Par exemple, la première chose à laquelle j'ai pensé quand je l'ai vue était: "cela peut ne pas fonctionner si la requête n'est pas valide", il s'avère que aujourd'hui cela fonctionne quand la requête n'est pas valide. Parce qu'avec l'implémentation actuelle, le contexte est évalué avant la validation de la requête. Cependant, c'est un détail d'implémentation qui peut changer à l'avenir. Par exemple, que se passe-t-il si un jour l'équipe apollo décide que ce serait un gain de performances d'évaluer le contexte uniquement après que la requête a été analysée et validée? C'est en fait ce à quoi je m'attendais :-)

Ce que j'essaie de dire, c'est que si vous voulez simplement enregistrer quelque chose rapidement pour déboguer quelque chose dans votre environnement dev, alors la solution d'Amit est définitivement la voie à suivre.

Toutefois, si vous souhaitez enregistrer des journaux pour un environnement de production, l'utilisation de la fonction context n'est probablement pas la meilleure idée. Dans ce cas, j'installerais le graphql-extensions et je les utiliserais pour la journalisation, quelque chose comme:

const { print } = require('graphql');

class BasicLogging {
  requestDidStart({queryString, parsedQuery, variables}) {
    const query = queryString || print(parsedQuery);
    console.log(query);
    console.log(variables);
  }

  willSendResponse({graphqlResponse}) {
    console.log(JSON.stringify(graphqlResponse, null, 2));
  }
}

const server = new ApolloServer({
  typeDefs,
  resolvers,
  extensions: [() => new BasicLogging()]
});

Éditer:

Comme Dan l'a souligné, il n'est pas nécessaire d'installer le graphql-extensions package car il a été intégré à l'intérieur du apollo-server-core paquet.

19
Josep

La solution de Dan résout principalement le problème, mais si vous souhaitez l'enregistrer sans utiliser express, vous pouvez le capturer dans le contexte indiqué dans l'exemple ci-dessous.

const server = new ApolloServer({
schema,
context: params => () => {
    console.log(params.req.body.query);
    console.log(params.req.body.variables);
}
});
7
Amit Bhoyar

Si je devais enregistrer la requête et les variables, j'utiliserais probablement apollo-server-express, au lieu de apollo-server, afin que je puisse ajouter un middleware express distinct avant graphql celui qui l'a enregistré pour moi:

const express = require('express')
const { ApolloServer } = require('apollo-server-express')
const { typeDefs, resolvers } = require('./graphql')

const server = new ApolloServer({ typeDefs, resolvers })
const app = express()

app.use(bodyParser.json())
app.use('/graphql', (req, res, next) => {
  console.log(req.body.query)
  console.log(req.body.variables)
  return next()
})

server.applyMiddleware({ app })

app.listen({ port: 4000}, () => {
  console.log(`???? Server ready at http://localhost:4000${server.graphqlPath}`)
})
3
Dan Crews