Apollo Server v4中GraphQL Context返回空对象的问题排查
解决Apollo Server v4中Context为空的问题
1. 配置HTTP请求(Query/Mutation)的Context
Apollo Server v4不再在ApolloServer构造函数中接收context参数,需在expressMiddleware中传入上下文生成函数,专门处理HTTP请求的上下文逻辑:
修改init函数里的app.use代码段:
app.use( '/graphql', cors<cors.CorsRequest>(), bodyParser.json(), // 为expressMiddleware添加context配置 expressMiddleware(server, { context: async ({ req }) => { // 从请求头提取认证信息,这里以Authorization为例 const authHeader = req.headers.authorization; let session = null; if (authHeader) { // 替换为你的实际认证逻辑,比如验证JWT // session = await verifyAuthToken(authHeader.split(' ')[1]); session = { userId: '123' }; // 示例认证数据 } // 返回包含pubsub和认证信息的上下文对象 return { session, pubsub }; }, }) );
配置完成后,Query和Mutation的解析器就能拿到非空的context对象。
2. 修复WebSocket订阅的Context逻辑
你定义的getSubscriptionContext仅在WebSocket订阅连接建立阶段执行,不会在HTTP查询时触发,所以之前执行Query看不到日志是正常现象。要让订阅解析器获取到上下文,需两步操作:
客户端传入连接参数
客户端建立WebSocket连接时,需携带认证相关的connectionParams(以Apollo Client为例):
const wsLink = new GraphQLWsLink( createClient({ url: 'ws://localhost:4000/graphql', connectionParams: { session: { userId: '123' }, // 替换为实际认证数据 }, }) );
服务端确认Context配置
你的服务端useServer配置逻辑没问题,可优化为更简洁的写法:
const serverCleanup = useServer( { schema, context: async (ctx: any) => { console.log('@@ WebSocket连接参数:', ctx.connectionParams); const session = ctx.connectionParams?.session || null; return { session, pubsub }; }, }, wsServer );
当客户端发起WebSocket订阅连接时,该函数会执行,订阅解析器即可获取到对应的上下文。
3. 验证效果
修改完成后:
- 执行Query/Mutation时,控制台会输出包含
session和pubsub的context对象; - 建立WebSocket订阅连接时,会打印连接参数,订阅解析器也能正常获取上下文。
内容的提问来源于stack exchange,提问作者Gwenda Thomas
相关产品推荐
相关产品推荐

