web-dev-qa-db-ja.com

Apollo Server 2 graphqlエンドポイントのみでExpressミドルウェアを使用するにはどうすればよいですか

Graphqlエンドポイントを除くすべてのルートでmorgantinyログステートメントを使用したいと思います。私は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 })
}

ありがとう!

6
Jared Dykstra

あなたが望むものを達成するためのいくつかの「ハッキー」な方法があります。代わりに、express.Routeを使用して各ルートにミドルウェアを登録できますが、特にリクエストではなく、GraphQLに関するより具体的なログが必要になると思います。

環境()

ApolloServer内のコールバックとして利用可能で、リクエストとレスポンスを含むオブジェクトを受け取ります。

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

fortmatResponse()

ApolloServer内のコールバックとして利用でき、応答とクエリを受け取ります。

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

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

ソース: formatResponsecontext

編集する

あなたができるもう1つのことは、req.pathが/graphQLパスと一致するかどうかをモーガンコールバックチェックでチェックし、その状況でのみログに記録することですが、これはmorganでExpress.Routeをログに記録することとほとんど同じです。

1
DobleL