嵌套查询/解析器时的 GraphQL.js 订阅响应错误
Posted
技术标签:
【中文标题】嵌套查询/解析器时的 GraphQL.js 订阅响应错误【英文标题】:GraphQL.js Subscription response error when nested queries/resolvers 【发布时间】:2019-04-27 03:37:50 【问题描述】:我有以下订阅查询工作正常:
subscription
streamShipmentOrder
id
但以下发送“无法读取未定义的属性'ShipmentOrder'”错误
subscription
streamShipmentOrder
id
logs
comment
这是我的 ShipmentOrder 类型定义,我使用sequelize 与数据库对话
const ShipmentOrderType = new GraphQLObjectType(
name: 'ShipmentOrder',
fields: () => (
id: type: GraphQLID ,
logs:
type: new GraphQLList(LogType),
resolve: async (parent, args, models , info) =>
return await models.ShipmentOrder.findOne(
where: id: parent.id ,
include: [ model: models.Log ],
).then((data) => data.logs);
,
这里是订阅定义
const ShipmentOrderSubscription = new GraphQLObjectType(
name: 'Subscription',
fields: () => (
streamShipmentOrder:
type: ShipmentOrderType,
resolve: (payload) => payload.shipmentOrderData,
subscribe: () =>
socket.asyncIterator([
SHIPMENT_ORDER_CREATED,
SHIPMENT_ORDER_UPDATED,
SHIPMENT_ORDER_DELETED
]),
,
),
);
以及触发订阅的突变,(在请求嵌套结果时,突变也可以正常工作)
const ShipmentOrderMutation = new GraphQLObjectType(
name: 'Mutation',
fields: () => (
createShipmentOrder:
type: ShipmentOrderType,
args: ...,
resolve: async (parent, args, models , info) =>
// create shipmentOrder
return await models.ShipmentOrder.create(...)
.then(async (createdShipmentOrder) =>
// create log and relate to created shipmentOrder
await models.Log.create(...);
// get created shipmentOrder with its logs
return await models.ShipmentOrder.findOne(
where: id: createdShipmentOrder.id ,
include: [ model: models.Log ],
).then((foundShipmentOrder) =>
// updates streams
socket.publish(SHIPMENT_ORDER_CREATED,
shipmentOrderData: foundShipmentOrder,
);
return foundShipmentOrder;
);
)
);
我可能会错过什么?
【问题讨论】:
推测,models
在 logs
字段的解析器中未定义。您如何在该文件中导入models
?该对象是如何导出的?您是否使用此处概述的“关联”模式 (github.com/sequelize/express-example) 来防止循环依赖?
是的@DanielRearden,关联适用于所有其他查询和突变,当仅询问主要类型时,每个订阅也适用,只有在询问其他“子属性”或关系时才会崩溃订阅中的 graphql 响应对象,就像在这个问题案例中一样。
@DanielRearden 你哪里对了! Log 解析器上下文在调用查询和变异时包含 model 对象,但在调用订阅时为空!!我还在想为什么...
【参考方案1】:
正如@DanielRearden 指出的那样,调用订阅时上下文为空,这弄乱了我的关系,这因为上下文在查询/突变和订阅上的处理方式不同.
所以解决的问题是将我的 models 对象添加到 ApolloServer 中 subscriptions 选项的 onConnect 属性,并传递与我相同的对象已经传递给我的上下文选项
const server = new ApolloServer(
schema,
subscriptions:
onConnect: () => (models),
,
context: () => (models)
【讨论】:
以上是关于嵌套查询/解析器时的 GraphQL.js 订阅响应错误的主要内容,如果未能解决你的问题,请参考以下文章