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
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.
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 馃檹