web-dev-qa-db-ja.com

ログapollo-server GraphQLクエリとリクエストごとの変数

Apollo-server 2.2.1以降を使用している場合、リクエストごとに、クエリと変数をどのようにログに記録できますか?

これは単純な要件と一般的な使用例のように見えますが、ドキュメントは very vague であり、queryオブジェクトはformatResponseに渡されます もはや =にはqueryStringおよびvariablesプロパティがあります。

8
Dan Dascalescu

Amitの回答は(今日)機能しますが、IMHOは少しハックで、将来期待どおりに機能しないか、一部のシナリオでは正しく機能しない可能性があります。

たとえば、私がそれを見て最初に思ったのは、「クエリが無効な場合は機能しない可能性がある」ということです。クエリが無効な場合はtodayが機能することがわかります。現在の実装では、クエリが検証される前にコンテキストが評価されるためです。ただし、これは将来変更される可能性のある実装の詳細です。たとえば、ある日アポロチームが、クエリが解析および検証された後にのみコンテキストを評価することがパフォーマンスの勝利であると決定した場合はどうなるでしょうか。それが実際に私が期待していたことです:-)

私が言おうとしているのは、dev環境で何かをデバッグするために何かをすばやくログに記録したい場合、Amitのソリューションが間違いなく進むべき方法であるということです。

ただし、本番環境のログを登録する必要がある場合は、context関数を使用することはおそらく最善のアイデアではありません。その場合、私はgraphql-extensionsをインストールして、次のようなログに使用します。

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

編集:

Danが指摘したように、graphql-extensionsパッケージ内に統合されているため、apollo-server-coreパッケージをインストールする必要はありません。

19
Josep

ダンのソリューションはほとんど問題を解決しますが、エクスプレスを使用せずにログを記録したい場合は、以下のサンプルに示すコンテキストでキャプチャできます。

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

クエリと変数をログに記録する必要がある場合は、おそらくapollo-server-express、 の代わりに apollo-server、それを記録したgraphqlの前に別のExpressミドルウェアを追加できるように:

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