Apollo GraphQL - 订阅响应中不包含相关类型

Posted

技术标签:

【中文标题】Apollo GraphQL - 订阅响应中不包含相关类型【英文标题】:Apollo GraphQL - Associated types not included on Subscription response 【发布时间】:2020-01-10 17:43:48 【问题描述】:

假设我有一个帖子和评论模型。一个帖子有很多评论。在 React Apollo 中,我在特定帖子的查询中使用 subscribeToMore。

查询显示如下:

query getPost(id: ID!)
    id, title, comments  id 

以及返回带有任何新 cmets 的帖子的订阅:

subscription commentAdded(postId: ID!)
    id, title, comments  id 

查询有效。它返回所有关联的评论,然后我可以将其呈现为页面上的列表。

然而,当使用 subscribeToMore 帮助器进行查询时,每当调度事件订阅时,我都会收到以下错误。

Cannot read property 'Comment' of undefined.

奇怪的是,如果我删除评论,订阅看起来像......

subscription commentAdded(postId: ID!)
    id, title

...完美运行。我很困惑为什么它似乎将评论视为与未定义的模型相关联。

这不仅仅是评论 -> 帖子问题,这发生在任何尝试返回关联订阅的模型上。

发布查询:

    post: async (parent, id, models) => 
        return await models.Post.findByPk(id);
    

saveComment 解析器:

    saveComment: async (parent, postId, comment, models, me) => 
        let post = await models.Post.findByPk(postId);
        let comment = await models.Comment.create(comment, postId);
        await pubsub.publish("COMMENT_CREATED", 
            commentCreated: post,
            postId
        )
    

commentCreated 订阅:

    commentCreated: 
        subscribe: withFilter(
            () => pubsub.asyncIterator(["COMMENT_CREATED"]),
            (payload, variables) => 
                return payload.postId == variables.postId
            
        )
    

帖子类型解析器

Post: 
    comments: async (post, args, models) => 
        return await models.Comment.findAll(where:postId: post.id);
    

服务器初始化:

const server = new ApolloServer(
    typeDefs: schema,
    resolvers,
    subscriptions: 
        onConnect: (connectionParams, webSocket) => 
            return true
        ,
    ,
    context: async ( req, connection ) => 
        if(connection)
            return connection.context;
        else
            const me = await getMe(req);
            return 
                models,
                me,
                secret: process.env.SECRET,
            ;
        
    
);

【问题讨论】:

请编辑您的问题以包含相关的解析器。 已编辑。这很奇怪,因为订阅有效,因为它包含初始模型,但是关联不起作用。而且我知道关联输入正确,因为它们在查询中起作用。这似乎与订阅设置有关,但我不确定。 我可以对其进行设置,以便在每次添加响应数据时触发新查询,这很有效,但对于应该非常简单的事情来说,这是一个烦人的工作。 所以这听起来像是您的context 函数的问题。订阅is a bit wonky 的上下文。你能把它也包括进去吗? 【参考方案1】:

您的context 函数仅返回connection.context,它不会包含您想要包含的任何自定义属性(memodels 等)。这样做应该可以解决问题:

context: async ( req, connection ) => 
  const context = 
    models,
    secret: process.env.SECRET,
  ;

  if(connection)
    return  ...connection.context, ...context ;
   else 
    const me = await getMe(req);
    return  ...context, me ;
  

【讨论】:

以上是关于Apollo GraphQL - 订阅响应中不包含相关类型的主要内容,如果未能解决你的问题,请参考以下文章

Apollo graphQL 客户端中的 CORS 异常“Access-Control-Allow-Headers 在预检响应中不允许请求标头字段内容类型”

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

Apollo graphQL 订阅使用哪个包

Apollo GraphQL 订阅

Angular Apollo GraphQL watchQuery 与订阅

Apollo - Angular 应用程序中子组件的多个 graphql 订阅