如何仅将快速中间件与Apollo Server 2 graphql端点一起使用

Jar*_*tra 5 node.js express apollo graphql apollo-server

我想对所有路由都使用morgantinylog语句,但graphql端点除外。我正在使用express和Apollo 2,但还无法使中间件与Express一起使用。如代码示例所示,我可以为整个express应用程序安装中间件,但是我想限制范围。

我的第一个尝试是创建一个express.router()并将路由器传递给apolloServer.applyMiddleware,但这似乎不起作用。

我想使用- morgan但我也想使用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 })
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Dob*_*leL 5

There are some 'Hacky' ways to achieve what you desire. You can use express.Route to register middlewares on each route instead, but I think that you may want more specific logs about GraphQL rather than the request in particular.

context()

作为 ApolloServer 内部的回调,它接收带有请求和响应的对象。

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

格式响应()

作为 ApolloServer 内部的回调,它接收响应和查询。

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

    // notice you must return the response
    return res;
  },
});
Run Code Online (Sandbox Code Playgroud)

来源: formatResponse上下文

编辑

您可以做的另一件事是在 morgan 回调上检查 req.path 是否与/graphQL路径匹配,并仅在这种情况下记录,但这与使用 morgan 记录 Express.Route 非常相似