【问题标题】:prisma2 subscriptions returns data: nullprisma2 订阅返回数据: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' } }

我有什么遗漏吗?

【问题讨论】:

    标签: prisma prisma-graphql graphql-subscriptions nexus-prisma


    【解决方案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;
                    }
                )
            });
    

    看来这可能是一个错误?

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 2021-12-05
      • 2021-05-21
      • 1970-01-01
      • 2016-07-20
      • 2019-01-10
      • 1970-01-01
      • 2020-05-06
      • 1970-01-01
      相关资源
      最近更新 更多