【问题标题】:GraphQL.js Subscription response error when nested queries/resolvers嵌套查询/解析器时的 GraphQL.js 订阅响应错误
【发布时间】: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;

                    });
                }
            }
        }
    })
});

我可能会错过什么?

【问题讨论】:

  • 推测,modelslogs 字段的解析器中未定义。您如何在该文件中导入models?该对象是如何导出的?您是否使用此处概述的“关联”模式 (github.com/sequelize/express-example) 来防止循环依赖?
  • 是的@DanielRearden,关联适用于所有其他查询和突变,当仅询问主要类型时,每个订阅也适用,只有在询问其他“子属性”或关系时才会崩溃订阅中的 graphql 响应对象,就像在这个问题案例中一样。
  • @DanielRearden 你哪里对了! Log 解析器上下文在调用查询和变异时包含 model 对象,但在调用订阅时为空!!我还在想为什么...

标签: graphql-js apollo-server graphql-subscriptions


【解决方案1】:

正如@DanielRearden 指出的那样,调用订阅时上下文为空,这弄乱了我的关系,这因为上下文在查询/突变和订阅上的处理方式不同.

所以解决的问题是将我的 models 对象添加到 ApolloServer 中 subscriptions 选项的 onConnect 属性,并传递与我相同的对象已经传递给我的上下文选项

const server = new ApolloServer({
    schema,
    subscriptions: {
        onConnect: () => ({models}),
    },
    context: () => ({models})
}

【讨论】:

    猜你喜欢
    • 2018-09-23
    • 2023-04-01
    • 1970-01-01
    • 2019-09-12
    • 2019-10-14
    • 2015-02-08
    • 2017-03-04
    • 1970-01-01
    • 2020-02-04
    相关资源
    最近更新 更多