web-dev-qa-db-fra.com

Comment utiliser un middleware express avec uniquement Apollo Server 2 graphql

Je souhaite utiliser les instructions morgan du journal tiny pour toutes mes routes, à l'exception des points de terminaison graphql. J'utilise express et Apollo 2 et je n'ai pas réussi à faire fonctionner un middleware avec express. Comme le montre l'exemple de code, je peux installer un middleware pour l'ensemble de l'application Express, mais je souhaite limiter la portée.

Ma première tentative a été de créer une express.router() et de transmettre le routeur à apolloServer.applyMiddleware, mais cela ne semble pas fonctionner.

Je veux utiliser morgan-- mais je veux aussi utiliser le middleware express-jwt.

import morgan from 'morgan'
import { mergeSchemas } from 'graphql-tools'
import { ApolloServer } from 'apollo-server-express'

import assessmentSchema from './assessment/schema'
import AssessmentAPI from './assessment/dataSource'

import userSchema from './user/schema'
import UserAPI from './user/dataSource'

/**
 * Installs apollo-server to handle requests under `path`
 * @param {*} app Express instance
 * @param {*} path route path, like '/graphql'
 */
export const createApi = (app, path) => {
  const dataSources = () => ({
    assessmentAPI: new AssessmentAPI({ store: 'intentionally undefined' }),
    userAPI: new UserAPI()
  })

  const schema = mergeSchemas({
    schemas: [assessmentSchema, userSchema]
  })

  morgan.token('graphql-query', req => {
    const { operationName } = req.body
    return `GRAPHQL: Operation Name: ${operationName}`
  })

  // TODO: Add custom logging middleware for GraphQL queries/mutations
  // The next line would add middleware to all of express, but I only want this style of logging for graphQL

  /*** Question is about the following line ***/
  // app.use(morgan(':graphql-query'))

  const apolloServer = new ApolloServer({ schema, dataSources })
  apolloServer.applyMiddleware({ app, path })
}

Merci!

3
Jared Dykstra

Il y a des façons "hackeuses" de réaliser ce que vous désirez. Vous pouvez utiliser express.Route pour enregistrer des middlewares sur chaque route, mais je pense que vous voudrez peut-être des journaux plus spécifiques sur GraphQL plutôt que la requête en particulier.

le contexte()

Disponible sous forme de rappel dans ApolloServer, il reçoit un objet avec la demande et la réponse.

const myServer =  new ApolloServer({
  schema: ...,
  context:({ req, res }) => { 
    // log here
  }
});

réponse fortmat ()

Disponible sous forme de rappel dans ApolloServer, il reçoit la réponse et la requête.

const server = new Apollo.ApolloServer({
  schema: ...,
  formatResponse: (res, query) => {
    // log here

    // notice you must return the response
    return res;
  },
});

Sources: formatResponse , context

Modifier

Une autre chose que vous pouvez faire est sur morgan callback vérifier si le chemin req.path correspond au chemin /graphQL, et ne vous connectez que dans cette situation, mais cela ressemble beaucoup à la connexion d'un Express.Route avec morgan

1
DobleL