使用apollo-server 2.2.1或更高版本时,如何为每个请求记录查询和变量?
这似乎是一个简单的要求和常见用例,但文档是very vague,传递给query
formatResponse
的no longer对象具有queryString
和variables
属性。
Amit的答案有效(今天),但恕我直言,它有点hacky,它可能在将来无法正常工作,或者在某些情况下可能无法正常工作。
例如,当我看到它时,我想到的第一件事是:“如果查询无效,那可能不起作用”,事实证明,今天它在查询无效时确实有效。因为使用当前实现,在验证查询之前评估上下文。但是,这是一个可以在将来改变的实现细节。例如,如果有一天阿波罗团队决定只有在解析和验证查询之后评估上下文才会获得性能?这实际上是我所期待的:-)
我想说的是,如果你只是想快速记录一些东西以便在你的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
软件包中。
Dan的解决方案主要解决问题,但如果您想在不使用express的情况下记录它,您可以在下面的示例中显示上下文中捕获它。
const server = new ApolloServer({
schema,
context: params => () => {
console.log(params.req.body.query);
console.log(params.req.body.variables);
}
});
如果我必须记录查询和变量,我可能会使用apollo-server-express
而不是apollo-server
,这样我就可以在graphql
之前添加一个单独的快速中间件,为我记录:
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}`)
})