NodeJS中GraphQL Apollo Server的context函数无限执行问题
问题:Apollo Server中context函数无限执行,持续打印日志
在NodeJS环境的GraphQL Apollo Server中,为了获取请求头的值使用了context函数,但该函数出现无限执行的情况,控制台持续打印“abcd”。
代码片段
const server = new ApolloServer({ schema: buildSubgraphSchema([{ typeDefs, resolvers }]), context:((req)=>{ // some code console.log("abcd"); return "hello" }) });
完整服务端代码
const dotenv = require('dotenv') dotenv.config({ path: './.env' }) const mongoose = require("mongoose"); const { typeDefs } = require("./schema/user"); const { resolvers } = require("./resolvers/resolver"); const { ApolloServer } = require("apollo-server"); const {buildSubgraphSchema} = require('@apollo/subgraph') const server = new ApolloServer({ schema: buildSubgraphSchema([{ typeDefs, resolvers }]), context:((req)=>{ // some code console.log("abcd"); return "hello" }) }); const PORT = process.env.PORT || 5000; mongoose.connect( process.env.MONGO_URI, { useNewUrlParser: true } ); const db = mongoose.connection; db.on("error", console.error.bind(console, "connection error:")); db.once("open", function () { console.log("Connected to MongoDB"); server.listen(PORT, () => console.log(`Server started on port ${PORT}`)); });
排查与解决方法
1. 定位重复请求来源
context每次执行都对应一个新请求,持续打印说明有客户端在不断发起请求。在context中添加请求信息打印,快速定位:
context: ({ req }) => { console.log(`触发请求: ${req.method} ${req.path}`); console.log("abcd"); return { req }; }
常见的重复请求来源:
- Apollo Playground/Studio的自动刷新/轮询功能,关闭即可
- 前端代码中的定时请求
- 网关或监控服务的健康检查请求
2. 修正context的正确写法
你的context返回了字符串,而通常context需要返回对象,方便后续resolver从context中获取数据。同时,正确获取请求头的方式如下:
context: ({ req }) => { // 从req对象中提取请求头 const authToken = req.headers.authorization?.split(' ')[1]; const userAgent = req.headers['user-agent']; // 返回对象,供resolver使用 return { authToken, userAgent, req // 也可以直接把整个req对象传入 }; }
3. 检查resolver是否存在循环调用
如果resolver内部存在循环调用(比如某个字段的resolver又发起了相同的查询),会导致不断触发请求,进而重复执行context。检查你的resolver代码,避免此类逻辑。
内容的提问来源于stack exchange,提问作者Harshil Sharma
相关产品推荐
相关产品推荐

