Apollo GraphQL订阅是否支持嵌套查询?嵌套查询报错求助
Apollo GraphQL订阅是否支持嵌套查询?
首先明确说:Apollo GraphQL订阅完全支持嵌套查询,你遇到的"Cannot read property 'User' of undefined"错误,和订阅本身的嵌套能力无关,问题出在你的Resolver逻辑或者数据模型的关联配置上。
问题场景回顾
你原本的订阅代码可以正常运行:
subscription voucherSent($estId: Int!) { voucherSent(estId: $estId) { id name usedAt sentAt } }
但添加了owner嵌套字段后就报错:
subscription voucherSent($estId: Int!) { voucherSent(estId: $estId) { id name usedAt sentAt owner { id username } } }
报错原因分析
这个错误说明在处理owner这个嵌套字段的Resolver里,代码尝试访问models.User,但models对象是undefined。常见的原因有这几个:
- 你没有为
Voucher类型的owner字段定义对应的Resolver,或者Resolver里没有正确获取到包含User模型的上下文(context); - 订阅Resolver返回的
Voucher实例没有预加载owner关联数据,而自动生成的默认Resolver又无法访问到User模型; - Apollo Server的上下文(context)没有正确注入
models对象,导致所有Resolver都拿不到数据模型。
解决步骤
给你几个具体的排查和修复方向:
检查
Voucher.owner的Resolver配置
确保你为Voucher类型的owner字段写了正确的Resolver,并且能从上下文拿到models:const resolvers = { Voucher: { owner: (parent, args, { models }) => { // 这里要确保models.User存在,比如通过parent.ownerId去查询User return models.User.findByPk(parent.ownerId); } }, // 你的订阅Resolver... Subscription: { voucherSent: { subscribe: () => ..., resolve: (payload) => payload.voucherSent } } };预加载关联数据(如果用ORM的话)
如果你用的是Sequelize这类ORM,在更新并返回Voucher的时候,可以用include选项预加载owner数据,这样嵌套字段就能直接拿到数据,不需要额外Resolver(当然有Resolver也可以覆盖):// 你的订阅相关Resolver代码示例 return models.Voucher.update( { sentAt: moment().format(), usedIn: ... }, { where: { /* 你的查询条件 */ }, returning: true, // 确保返回更新后的记录 include: [models.User] // 预加载owner关联数据 } ).then(([_, [updatedVoucher]]) => updatedVoucher);确认上下文的
models注入
检查Apollo Server的初始化代码,确保你把models正确传递到上下文里,这样所有Resolver都能访问到:const server = new ApolloServer({ typeDefs, resolvers, context: () => ({ models }) // 这里要确保models是正确引入的实例 });
总结
订阅本身完全支持嵌套查询,你遇到的问题是数据关联的Resolver或者模型访问配置错误,按照上面的步骤排查,应该就能解决这个报错啦~
内容的提问来源于stack exchange,提问作者Thierry D.
相关产品推荐
相关产品推荐

