Subscriptions
Overview
How are subscriptions in the Prisma API generated?
The GraphQL API of a Prisma service is specified in the Prisma GraphQL schema. The Prisma GraphQL schema is auto-generated based on the service's datamodel:

The Subscription type of the Prisma GraphQL schema defines all the subscriptions the Prisma API accepts.
As an example, consider the following datamodel:
type User {
id: ID! @unique
name: String!
}
This is the Subscription type Prisma will generate:
type Subscription {
user(where: UserSubscriptionWhereInput): UserSubscriptionPayload
}
For every type in your datamodel, one subscription is generated. Taking above the above User type as an example, this subscription is:
user: Fires whenever aUsernode is created, updated or deleted. (Except for batch mutations).
To inspect all the available operations of your Prisma API in detail, you can read the Prisma GraphQL schema of your Prisma service. It can be downloaded with the GraphQL CLI:
graphql get-schema --endpoint __YOUR_PRISMA_ENDPOINT__ --output prisma.graphql --no-all
Another way to learn about the concrete capabilities of your Prisma API is by exploring the auto-generated API documentation inside a GraphQL Playground. You can do so by clicking the green SCHEMA-button at the right edge of the Playground:

Datamodel for examples on this page
All example subscriptions on this page are based on a Prisma service configured with this datamodel:
type Post {
id: ID! @unique
title: String!
published: Boolean! @default(value: "false")
author: User
}
type User {
id: ID! @unique
name: String!
posts: [Post!]!
}
Understanding Prisma’s subscription API
Prisma lets you subscribe to three different kinds of events (per type in your datamodel). Taking the Post type from above datamodel as an example, these events are:
- a new
Postnodes is created - an existing
Postnodes is updated - an existing
Postnodes is deleted
Subscriptions are not firing for batch mutations.
The corresponding definition of the Subscription type looks as follows (this definition can be found in the Prisma GraphQL schema):
type Subscription {
post(where: PostSubscriptionWhereInput): PostSubscriptionPayload
}
Here is what a sdle subscription operation looks like:
subscription {
post {
node {
id
title
}
}
}
If not further constrained through the where argument, the post subscription will fire for all of the events mentioned above. Which fields of the PostSubscriptionPayload are included in messages from the server depends on the kind of event.
Filtering for specific events
The where argument allows clients to specify exactly what events they’re interested in. Maybe a client always only wants to receive updates when...
- ... a
Postgets deleted - ... a
Postwhere thetitlecontains a specific keyword is created
These kinds of constraints can be expressed using the where argument. The type of where is PostSubscriptionWhereInput:
input PostSubscriptionWhereInput {
# Filter for a specific mutation:
# CREATED, UPDATED, DELETED
mutation_in: [MutationType!]
# Filter for a specific field being updated
updatedFields_contains: String
updatedFields_contains_every: [String!]
updatedFields_contains_some: [String!]
# Filter for concrete values of the Post being mutated
node: PostWhereInput
# Combine several filter conditions
AND: [PostSubscriptionWhereInput!]
OR: [PostSubscriptionWhereInput!]
}
The two examples mentioned above could be expressed with the following subscriptions in the Prisma API:
# Only fire for _deleted_ posts
subscription {
post(where: {
mutation_in: [DELETED]
}) {
# ... we'll talk about the selection set in a bit
}
}
# Only fire when a post whose title contains "GraphQL" is _created_
subscription {
post(where: {
mutation_in: [CREATED]
node: {
title_contains: "GraphQL"
}
}) {
# ... we'll talk about the selection set in a bit
}
}
Exploring the selection set of a subscription
You now have a good understanding how you can subscribe to the events that interest you. But how can you now ask for the data related to an event?
The PostSubscriptionPayload type defines the fields which you can request in a post subscription. Here is what it looks like:
type PostSubscriptionPayload {
mutation: MutationType!
node: Post
updatedFields: [String!]
previousValues: PostPreviousValues
}
Here's an overview of the values for each field according to the event that triggered the subscription:
mutation | node | previousValues | updatedFields |
|---|---|---|---|
CREATE | The created node | null | null |
UPDATE | The new values of the updated node | The values of the updated node before the update | A list of strings with the names of the fields that were updated |
DELETE | null | The deleted node | null |
In the following, each field is discussed in more detail.
mutation
The mutation field has the type MutationType. MutationType is an enum with three values:
enum MutationType {
CREATED
UPDATED
DELETED
}
The mutation field on the PostSubscriptionPayload type therefore carries the information what kind of mutation happened.
node
The node field has the Post type. It represents the Post element which was created or updated and lets you retrieve further information about it.
Notice that for DELETED-mutations, node will always be null. If you need to know more details about deleted Post node, you can use the previousValues field instead (more about that soon).
updatedFields
updatedFields is of type [String!].
One piece of information you might be interested in for UPDATED-mutations is which fields have been updated with a mutation. That’s what the updatedFields field is used for.
Assume a client has subscribed to the Prisma API with the following subscription:
subscription {
post {
updatedFields
}
}
Now, assume the server receives the following mutation to update the title of a given Post:
mutation {
updatePost(
where: { id: "..." }
data: { title: "Prisma is the best way to build GraphQL servers" }
) {
id
}
}
The subscribed client will then receive the following payload:
{
"data": {
"post": {
"updatedFields": ["title"]
}
}
}
This is because the mutation only updated the Post node's title field - nothing else.
previousValues
previousValues is of type PostPreviousValues. This type looks very similar to Post itself:
type PostPreviousValues {
id: ID!
title: String!
}
It basically is a helper type mirroring the fields from Post.
previousValues is only used for UPDATED- and DELETED-mutations. For CREATED-mutations, it will always be null (for the same reason that node is null for DELETED-mutations).
Putting everything together
Consider again the sample updatePost mutation from before. But now assume, the subscription query includes all the fields we just discussed:
subscription {
post {
mutation
updatedFields
node {
title
}
previousValues {
title
}
}
}
Here’s what the payload will look like that the server pushes to the client after it performed the mutation from before:
{
"data": {
"post": {
"mutation": "UPDATED",
"updatedFields": ["title"],
"node": {
"title": "Prisma is the best way to build GraphQL servers"
},
"previousValues": {
"title": "GraphQL servers are best built with conventional ORMs"
}
}
}
}
Note that this assumes the updated Post had the following title before the mutation was performed: “GraphQL servers are best built with conventional ORMs”.
Object subscriptions
For every available object type in your datamodel, one object subscription is automatically generated.
Subscribing to created nodes
For a given type, you can subscribe to all nodes that are being created using the generated object subscription.
Subscribe to all created nodes
To subscribe to created nodes of a certain type, you can use the generated object subscription and specify the mutation_in: [CREATED] filter for the where argument.
Subscribe to created Post nodes:
subscription {
post(where: { mutation_in: [CREATED] }) {
mutation
node {
description
imageUrl
author {
id
}
}
}
}
Subscribe to specific created nodes using filters
You can make use of a similar filter system as for queries using the node argument of the where object.
Subscribe to created Post nodes of a specific author:
subscription {
post(
where: {
AND: [
{ mutation_in: [CREATED] }
{ node: { author: { id: "cj03x3nacox6m0119755kmcm3" } } }
]
}
) {
mutation
node {
description
imageUrl
author {
id
}
}
}
}
Subscribing to deleted nodes
To subscribe to deleted nodes of a certain type, you can use the generated object subscription and specify the mutation_in: [DELETED] filter for the where argument.
Subscribe to all deleted nodes
Subscribe to deleted Post nodes:
subscription deletePost {
post(where: { mutation_in: [DELETED] }) {
mutation
previousValues {
id
}
}
}
Subscribe to specific deleted nodes
You can make use of a similar filter system as for queries using the node argument of the where object.
Subscribe to deleted Post nodes where the title contains a certain string:
subscription {
post(where: { mutation_in: [DELETED], node: { title_contains: "GraphQL" } }) {
mutation
previousValues {
id
}
}
}
Subscribing to updated nodes
To subscribe to updated nodes of a certain type, you can use the generated object subscription and specify the mutation_in: [UPDATED] filter for the where argument.
Subscribe to all updated nodes
Subscribe to updated Post nodes:
subscription {
post(where: { mutation_in: [UPDATED] }) {
mutation
updatedFields
node {
description
imageUrl
}
previousValues {
description
imageUrl
}
}
}
Subscribe to specific field updates
Subscribe to events where the description field of a Post node gets updated:
subscription {
post(
where: { mutation_in: [UPDATED], updatedFields_contains: "description" }
) {
mutation
node {
description
}
updatedFields
previousValues {
description
}
}
}
Similarly to updatedFields_contains, more filter conditions exist:
updatedFields_contains_every: [String!]: Matches if all fields specified have been updated.updatedFields_contains_some: [String!]: Matches if some of the specified fields have been updated.
Subscribe to events where the description and published fields of a Post node gets updated:
subscription {
post(
where: {
mutation_in: [UPDATED]
updatedFields_contains_every: ["description", "published"]
}
) {
mutation
node {
description
}
updatedFields
previousValues {
description
}
}
}
Subscribe to events where the description or published fields of a Post node gets updated:
subscription {
post(
where: {
mutation_in: [UPDATED]
updatedFields_contains_some: ["description", "published"]
}
) {
mutation
node {
description
}
updatedFields
previousValues {
description
}
}
}
It is not possible to use the updatedFields filter together with mutation_in: [CREATED] or mutation_in: [DELETED] as it only applied to UPDATE events!
Relation subscriptions
Currently, subscriptions for relation updates are only available with a workaround using UPDATED subscriptions.
You can force a notification by "touching" nodes. Add a dummy: String field to the type in question and update this field for the node whose relation status just changed.
mutation updatePost {
updatePost(
where: { id: "some-id" }
data: {
dummy: "dummy" # do a dummy change to trigger update subscription
}
)
}
If you're interested in a direct relation trigger for subscriptions, please join the discussion on GitHub.