GraphQL 订阅字段无法访问解析器的上下文

Posted

技术标签:

【中文标题】GraphQL 订阅字段无法访问解析器的上下文【英文标题】:GraphQL Subscription fields not able to access context of resolver 【发布时间】:2021-10-16 04:05:21 【问题描述】:

我正在关注Learning GraphQL 这本书,在实现订阅时遇到了一个问题。从订阅中查看对象时,发送到订阅的对象的其中一个字段的解析器不起作用,但奇怪的是,它适用于突变和查询。有问题的解析器如下所示:

Photo: 
    postedBy: (parent, args, db) => db.collection('users').findOne(githubLogin: parent.userID)

当我进行以下突变时,我收到了postedBy 就好了:

mutation($input: PostPhotoInput!) 
    postPhoto(input: $input) 
        name
        url
        postedBy 
            name
        
    

当我进行返回该类型的查询时也是如此:


    allPhotos 
        name
        postedBy 
           name
        
    

但是当我开始以下订阅并进行它正在侦听的突变时:

subscription 
    newPhoto 
        name
        url
        postedBy 
            name
        
    

我收到错误无法读取未定义的属性“集合”。 如果我在没有postedBy 字段的情况下使用订阅,我不会收到错误消息。我只能假设未定义的对象是 db,它是从上下文中传入的。为什么这适用于查询和突变,但不适用于订阅?

有关更多上下文,这里是订阅的解析器:

Subscription: 
        newPhoto: 
            subscribe: () => pubsub.asyncIterator('photo-added')
        

这是发布订阅正在侦听的事件的突变的解析器:

async postPhoto(parent, input, db, currentUser) 
            if (!currentUser)
                throw new Error('Only an authorized user can post a photo');

            const newPhoto = 
                ...input,
                userID: currentUser.githubLogin,
                created: new Date()
            ;
            const insertedId = await db
                .collection('photos')
                .insertOne(newPhoto);
            newPhoto.id = insertedId;

            pubsub.publish('photo-added', newPhoto);

            return newPhoto;
        

【问题讨论】:

【参考方案1】:

我发现出了什么问题。事实证明,订阅不是从传递给 ApolloServer 构造函数的上下文函数中获取上下文,而是从传递给 SubscriptionServer 构造函数的 onConnect 函数中获取上下文,如docs 中所述。

【讨论】:

以上是关于GraphQL 订阅字段无法访问解析器的上下文的主要内容,如果未能解决你的问题,请参考以下文章

嵌套查询/解析器时的 GraphQL.js 订阅响应错误

无法解析自定义对象 graphql 架构

无法将自定义结果从解析器传递到 Graphql

GraphQL 解析器参数(根、参数、上下文)的错误顺序

无法理解使用带有 graphql-ruby gem 的 ActionCable 的 GraphQL 订阅

无法连接到 Graphql 订阅?