prisma2 订阅返回数据:null

Posted

技术标签:

【中文标题】prisma2 订阅返回数据:null【英文标题】:prisma2 subscriptions returns data: null 【发布时间】:2020-01-03 00:21:22 【问题描述】:

我有一个基本的 pubsub 使用样板和 graphql-yoga 在这里工作: https://github.com/ryanking1809/prisma2_subscriptions https://codesandbox.io/s/github/ryanking1809/prisma2_subscriptions/tree/sql-lite

带有发布突变:

const Mutation = objectType(
  name: 'Mutation',
  definition(t) 
   //...
    t.field('publish', 
      type: 'Post',
      nullable: true,
      args: 
        id: idArg(),
      ,
      resolve: async (parent,  id , ctx) => 
        const post = await ctx.photon.posts.update(
          where:  id ,
          data:  published: true ,
          include:  author: true 
        );
        ctx.pubsub.publish("PUBLISHED_POST", 
          publishedPost: post
        );
        return post
      ,
    )
  ,
)

还有一个订阅 - 我只是返回 true 以确保 withFilter(来自 graphql-yoga)正常工作。

const Subscription = objectType(
    name: "Subscription",
    definition(t) 
        t.field("publishedPostWithEmail", 
            type: "Post",
            args: 
                authorEmail: stringArg( required: false )
            ,
            subscribe: withFilter(
                (parent,  authorEmail , ctx) => ctx.pubsub.asyncIterator("PUBLISHED_POST"),
                (payload,  authorEmail ) => true
            )
        );
    
);

publish 上返回以下内容(您可以将这些内容复制并粘贴到代码沙箱中 - 这很整洁!)

mutation 
  publish(
    id: "cjzwz39og0000nss9b3gbzb7v"
  ) 
    id,
    title,
    author 
      email
    
  

subscription 
  publishedPostWithEmail(authorEmail:"prisma@subscriptions.com") 
    title,
    content,
    published
  


  "errors": [
    
      "message": "Cannot return null for non-nullable field Subscription.publishedPostWithEmail.",
      "locations": [
        
          "line": 2,
          "column": 3
        
      ],
      "path": [
        "publishedPostWithEmail"
      ]
    
  ],
  "data": null

由于某种原因,它返回了data: null。当我在过滤器函数中记录payload.publishedPosts 时,似乎一切都在那里。

 id: 'cjzwqcf2x0001q6s97m4yzqpi',
  createdAt: '2019-08-29T13:34:26.648Z',
  updatedAt: '2019-08-29T13:54:19.479Z',
  published: true,
  title: 'Check Author',
  content: 'Do you save the author?',
  author:
    id: 'sdfsdfsdfsdf',
     email: 'prisma@subscriptions.com',
     name: 'Prisma Sub'  

我有什么遗漏吗?

【问题讨论】:

【参考方案1】:

终于明白了! ?

订阅函数需要以pubsub中的key命名。 因此,如果您有如下发布功能:

ctx.pubsub.publish("PUBLISHED_POST", 
          publishedPost: post
        );

那么你必须将你的订阅命名为publishedPost

        t.field("publishedPost", 
            type: "Post",
            args: 
                authorEmail: stringArg( required: false )
            ,
            subscribe: withFilter(
                (parent,  authorEmail , ctx) =>
                    ctx.pubsub.asyncIterator("PUBLISHED_POST"),
                (payload,  authorEmail ) => payload.publishedPost.author.email === authorEmail
            )
        );

如果您将订阅命名为 publishedPostWithEmail,则不会返回任何数据

        t.field("publishedPostWithEmail", 
                //...
        );

有趣的是,如果你有 2 把钥匙

ctx.pubsub.publish("PUBLISHED_POST", 
          publishedPost2: post,
          publishedPost3: post
        );

如果您将订阅命名为 publishedPost2,那么结果中将省略 publishedPost3


奇怪的是,如果您订阅了 2 条消息,您将获得所有数据

ctx.pubsub.publish("PUBLISHED_POST", 
          publishedPost: post,
          publishedPost2: post
        );
        ctx.pubsub.publish("PUBLISHED_POST_X", 
          publishedPostX: post,
          publishedPostY: post
        );
ctx.pubsub.asyncIterator([
                        "PUBLISHED_POST",
                        "PUBLISHED_POST_X"
                    ]),

返回publishedPostpublishedPost2publishedPostXpublishedPostY

因此,您可以通过订阅具有单个项目的数组来解决上述问题,并且订阅的名称变得无关紧要。

        t.field("publishedPostXYZ", 
            type: "Post",
            args: 
                authorEmail: stringArg( required: false )
            ,
            subscribe: withFilter(
                (parent,  authorEmail , ctx) =>
                    ctx.pubsub.asyncIterator([
                        "PUBLISHED_POST"
                    ]),
                (payload,  authorEmail ) => 
                    return payload.publishedPost.author.email === authorEmail;
                
            )
        );

看来这可能是一个错误?

【讨论】:

以上是关于prisma2 订阅返回数据:null的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 复制本地订阅属性返回“无法将值‘null’应用于属性 ServerInstance:值不能为空。”

使用 Graphql 在 NestJS 上订阅时,“不能为不可为空的字段返回 null”

返回 Django 石墨烯订阅中订阅事件的初始数据

在另一个订阅中返回订阅数据

graphql 订阅返回空数据

Angular 6 - 无法订阅从服务返回的数据