Nexus: Subscription type checking error with Prisma $subscribe

Created on 15 Mar 2019  路  10Comments  路  Source: graphql-nexus/nexus

Hi everyone! Yesterday I鈥檝e implemented the subscription in my project using nexus/nexus-prisma. By default, function call prisma.$subscribe.type() returns asyncIterator which resolves as {node: Type, mutation: MutationType, updatedFields: [String], previousValue: TypePreviousValue} and this structure is convenient for my case. But if I use this asyncIterator in my subscription - nexus throws an error for the subscription in Playground, which says: Unknown prisma-client function for field TypeSubscriptionPayload.mutation, but in resolve function it's a normal object with normal values. Any ideas? Apollo server works fine it this case and I think that this problem related to the implementation of subscription on Nexus.

Packages versions:
nexus-prisma: 0.3.5
nexus: 0.11.3

Most helpful comment

Hey there,

I just released [email protected] which enable better support for subscription with nexus and the client.

I made a small guide here: https://github.com/prisma/nexus-prisma/releases/tag/v0.3.7

@gauthierrodaro @Devlin556

It should remove the need for you to redeclare all the subscription types. The code below is now enough for things to work 馃檹

export const SubscriptionUser = subscriptionField('users', {
  type: 'UserSubscriptionPayload',
  subscribe(root, args, ctx) {
    return ctx.prisma.$subscribe.user() as any
  },
  resolve(payload) {
    return payload
  },
})

All 10 comments

Hey there, the problem here is related to nexus-prisma which doesn't support subscriptions yet. Expect that to be fixed soon 馃檹

@Weakky I don't use nexus-prisma for subscriptions. I used nexus objectType field, which already support subscriptions and work with them.

Yes, but I assume you haven't defined TypeSubscriptionPayload yourself, nexus-prisma did it for you and generated (buggy) resolvers for that type automatically because it's trying to call client.subscriptionPayload(...).mutation() while it should just return the mutation value.

The error Unknown prisma-client function for field TypeSubscriptionPayload.mutation is something I thrown from nexus-prisma here: https://github.com/prisma/nexus-prisma/blob/master/packages/nexus-prisma/src/resolver.ts#L104

@Devlin556, @Weakky: Indeed, I made it work in one of my project.

You just have to write a lot of boilerplate code 馃槈

Here is an example:

// ...
const ReactionSubscriptionWhereInput = prismaInputObjectType({
  name: "ReactionSubscriptionWhereInput",
  definition(t) {
    t.prismaFields(["*"])
  }
})

const ReactionPreviousValues = prismaObjectType({
  name: "ReactionPreviousValues",
  definition(t) {
    t.prismaFields(["*"])
  }
})

const MutationType = prismaEnumType({
  name: "MutationType",
  members: ["CREATED", "UPDATED", "DELETED"]
})

const ReactionSubscriptionPayload = objectType({
  name: "ReactionSubscriptionPayload",
  definition(t) {
    t.field("mutation", {
      type: "MutationType",
      resolve: ({ mutation }) => mutation
    })
    t.field("node", {
      type: "Reaction",
      resolve: ({ node }) => node
    })
    t.string("updatedFields", {
      list: true,
      resolve: ({ updatedFields }) => updatedFields
    })
    t.field("previousValues", {
      type: "ReactionPreviousValues",
      resolve: ({ previousValues }) => previousValues
    })
  }
})

const ReactionSub = subscriptionField("reaction", {
  type: "ReactionSubscriptionPayload",
  args: {
    where: arg({ type: "ReactionSubscriptionWhereInput" })
  },
  subscribe: (parent, { where }, context) => {
    return context.prisma.$subscribe.reaction(where)
  },
  resolve: payload => {
    return payload
  }
})
// ...

Hey there,

I just released [email protected] which enable better support for subscription with nexus and the client.

I made a small guide here: https://github.com/prisma/nexus-prisma/releases/tag/v0.3.7

@gauthierrodaro @Devlin556

It should remove the need for you to redeclare all the subscription types. The code below is now enough for things to work 馃檹

export const SubscriptionUser = subscriptionField('users', {
  type: 'UserSubscriptionPayload',
  subscribe(root, args, ctx) {
    return ctx.prisma.$subscribe.user() as any
  },
  resolve(payload) {
    return payload
  },
})

@Weakky The as any is not necessary anymore since nexus 0.11.7 was released.

I tried to follow your guide, but there is a compilation error

   Types of property 'type' are incompatible.
      Type '"NotificationSubscriptionPayload"' is not assignable to type ...

Do I need to redefine NotificationSubscriptionPayload in my code like what @gauthierrodaro did?
But @Weakky said:

Yes, but I assume you haven't defined TypeSubscriptionPayload yourself, nexus-prisma did it for you and generated (buggy) resolvers for that type automatically because it's trying to call client.subscriptionPayload(...).mutation() while it should just return the mutation value.

import { subscriptionField } from 'nexus/dist'

export const NotificationSubscription = subscriptionField('notification', {
  type: 'NotificationSubscriptionPayload',
  subscribe: (_, args, context) => {
    return context.prisma.$subscribe.notification()
  },
  resolve(payload) {
    return payload
  },
})

Oh sorry my mistake, I don't have to redefine NotificationSubscriptionPayload.

Hey, @Weakky I tried your solution but it isn't working. Unfortunately, I don't get any type with Subscription in it. Mind taking a look at my StackOverflow question?

Edit: So on Prisma's Slack, I got the answer that Subscriptions aren't yet implemented in Prisma2's Photon 馃槶

Closing for lack of activity.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StevenLangbroek picture StevenLangbroek  路  6Comments

jasonkuhrt picture jasonkuhrt  路  5Comments

deadcoder0904 picture deadcoder0904  路  6Comments

tonyfromundefined picture tonyfromundefined  路  3Comments

MathiasKandelborg picture MathiasKandelborg  路  5Comments