Mutations
Overview
How are mutations 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 Mutation
type of the Prisma GraphQL schema defines all the mutations the Prisma API accepts.
As an example, consider the following datamodel:
type User {
id: ID! @unique
name: String!
}
This is the Mutation
type Prisma will generate:
type Mutation {
createUser(data: UserCreateInput!): User!
updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User
deleteUser(where: UserWhereUniqueInput!): User
upsertUser(
where: UserWhereUniqueInput!
create: UserCreateInput!
update: UserUpdateInput!
): User!
updateManyUsers(data: UserUpdateInput!, where: UserWhereInput!): BatchPayload!
deleteManyUsers(where: UserWhereInput!): BatchPayload!
}
For every type in your datamodel, six mutation are generated. Taking above the above User
type as an example, these mutations are:
createUser
: Create a newUser
nodeupdateUser
: Update an existingUser
nodedeleteUser
: Delete an existingUser
nodeupsertUser
: Update an existingUser
node; if it does not exist create a newUser
nodeupdateManyUsers
: Update manyUser
nodes at oncedeleteManyUsers
: Delete manyUser
nodes at once
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 mutations 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
age: Int
email: String! @unique
name: String!
posts: [Post!]!
}
Mutation concepts
The Prisma API offers three kinds of mutations:
- Object mutations: Create, update, upsert or delete a single node of a certain object type.
- Nested mutations: Create, update, upsert, delete, connect, disconnect multiple nodes of two or more related types.
- Batch mutations: Update and delete many nodes of a certain object type.
When working with the Prisma API, the following concepts are also useful to keep in mind:
- Relation mutations: Connect and disconnect two nodes in a relation (this is done via nested mutations).
- Input types: The Prisma API follows best practices of GraphQL mutation design and accepts mutation arguments as a single input object called
data
.
Object mutations
You can use object mutations to modify single nodes of a certain model.
Creating nodes
You can create new nodes using create
mutations. These mutations take one input object called data
wrapping all required fields of the respective type.
Create a new User
node:
mutation {
createUser(data: { age: 42, email: "alice@prisma.io", name: "Alice" }) {
id
name
}
}
Updating nodes
You can change the values of one or more fields of a node using an update
mutation. The node to be updated is selected using the where
argument and the new values are provided via the data
argument. Nodes can be selected by any field that's annotated with the @unique
directive.
Change the name
of a User
node identified by its id
:
mutation {
updateUser(
data: { name: "Alice" }
where: { id: "cjcdi63j80adw0146z7r59bn5" }
) {
id
name
}
}
Change the name
of a User
node identified by its email
:
mutation {
updateUser(data: { name: "Alice" }, where: { email: "alice@prisma.io" }) {
id
name
}
}
Upserting nodes
When you want to either update an existing node, or create a new one in a single mutation, you can use upsert mutations.
Update the User
with a certain email
, or create a new User
if a User
with that email
doesn't exist yet:
mutation {
upsertUser(
where: { email: "alice@prisma.io" }
create: { email: "alice@prisma.io", age: 42, name: "Alice" }
update: { age: 42 }
) {
name
}
}
Deleting nodes
To delete nodes, you need to select the node to be deleted via the where
argument in a delete
mutation.
Delete a User
node by its id
:
mutation {
deleteUser(where: { id: "cjcdi63l20adx0146vg20j1ck" }) {
id
name
email
}
}
Delete a User
node by its email
:
mutation {
deleteUser(where: { email: "cjcdi63l20adx0146vg20j1ck" }) {
id
name
email
}
}
Nested mutations
You can use create
and update
mutations to modify nodes across relations at the same time. This is referred to as nested mutations and is executed transactionally.
Several nested mutation arguments exist:
create
update
upsert
delete
connect
disconnect
Rather than mapping out all possible scenarios at this point, we provide a list of examples.
It's recommended to explore the behaviour of different nested mutations by using the GraphQL Playground.
Creating and connecting related nodes
You can use the connect
mutation within a nested input object field to connect to one or more related nodes.
Create a new Post
node and connect it to an existing User
node via the unique email
field:
mutation {
createPost(
data: {
title: "This is a draft"
author: { connect: { email: "alice@prisma.io" } }
}
) {
id
author {
name
}
}
}
If you provide a create
argument instead of connect
within author
, you would create a new User
node and at the same time connect the new Post
node to it:
mutation {
createPost(
data: {
title: "This is a draft"
author: { create: { name: "Bob", email: "bob@prisma.io", age: 42 } }
}
) {
id
author {
name
}
}
}
When using the createUser
instead of a createPost
mutation, you can actually create and connect to multiple Post
nodes at the same time, because User
has a to-many relation Post
.
Create a new User
node and directly connect it to several newly created Post
nodes:
mutation {
createUser(
data: {
name: "Bob"
email: "bob@prisma.io"
age: 42
posts: {
create: [
{ published: true, title: "Hello World" }
{ title: "GraphQL is great" }
]
}
}
) {
id
posts {
id
}
}
}
Create a new User
node and directly connect it to several newly created and existing Post
nodes:
mutation {
createUser(
data: {
name: "Bob"
email: "bob@prisma.io"
age: 42
posts: {
create: [
{ published: true, title: "Hello World" }
{ title: "GraphQL is great" }
]
connect: [
{ id: "cjcdi63j80adw0146z7r59bn5" }
{ id: "cjcdi63l80ady014658ud1u02" }
]
}
}
) {
id
posts {
id
}
}
}
Updating and upserting related nodes
When updating nodes, you can update one or more related nodes at the same time.
Update the title
of a Post
node that belongs to a certain User
node:
mutation {
updateUser(
data: {
posts: {
update: [
{
where: { id: "cjcf1cj0r017z014605713ym0" }
data: { title: "Hello World" }
}
]
}
}
where: { id: "cjcf1cj0c017y01461c6enbfe" }
) {
id
posts {
id
}
}
}
update
accepts a list of objects with where
and data
fields suitable for the updatePost
mutation.
Update the name
of an existing User
node or create a new User
node that belongs to a certain Post
node:
Nested upserting works similarly:
mutation {
updatePost(
where: { id: "cjcf1cj0r017z014605713ym0" }
data: {
author: {
upsert: {
where: { id: "cjcf1cj0c017y01461c6enbfe" }
update: { id: "cjcdi63l80ady014658ud1u02", name: "Alice" }
create: { email: "alice@prisma.io", name: "Alice", age: 42 }
}
}
}
) {
id
author {
id
}
}
}
Disconnecting a Post
node from a User
node:
mutation {
updateUser(
where: { id: "cjcf1cj0c017y01461c6enbfe" }
data: { posts: { disconnect: [{ id: "cjcdi63l80ady014658ud1u02" }] } }
) {
id
posts {
id
}
}
}
Deleting related nodes
When updating nodes, you can delete one or more related nodes at the same time.
Delete Post
nodes belonging to a certain User
node:
mutation {
updateUser(
data: {
posts: {
delete: [
{ id: "cjcf1cj0u01800146jii8h8ch" }
{ id: "cjcf1cj0u01810146m84cnt34" }
]
}
}
where: { id: "cjcf1cj0c017y01461c6enbfe" }
) {
id
}
}
Scalar list mutations
When an object type has a field that is has a scalar list as its type, there are a number of special mutations available.
In the following datamodel, the User
type has three such fields:
type User {
id: ID! @unique
scores: [Int!]! # scalar list for integers
friends: [String!]! # scalar list for strings
coinFlips: [Boolean!]! # scalar list for booleans
}
Creating nodes
When creating a new node of type User
, a list of values can be provided for each scalar list field using set
.
Create a new User
and set the values for scores
, friends
and coinFlips
:
mutation {
createUser(data: {
scores: { set: [1, 2, 3] }
friends: { set: ["Sarah", "Jane"] }
throws: { set: [false, false] }
}) {
id
}
}
Updating nodes
When updating an existing node of type User
, a number of additional operations can be performed on the scalar list fields (such as scores: [Int!]!
):
set
: Override the existing list with an entirely new list.push
(coming soon): Add one or more elements anywhere in the list.pop
(coming soon): Remove one or more elements from the beginning or the end of the list.remove
(coming soon): Remove all elements from the list that match a given filter.
push
,pop
andremove
are not yet implemented. If you're curios what these are going to look like, you can get a preview in the respective specification.
Each scalar list field takes an object with a set
field in an update
mutation. The value of that field is a single value or a list of the corresponding scalar type.
Set the scores
of an existing User
node to [1]
:
mutation {
updateUser(
where: { id: "cjd4lfdyww0h00144zst9alur" }
data: { scores: { set: 1 } }
) {
id
}
}
Set the scores
of an existing User
node to [10,20,30]
:
mutation {
updateUser(
where: { id: "cjd4lfdyww0h00144zst9alur" }
data: { scores: { set: [10, 20, 30] } }
) {
id
}
}
Batch Mutations
Batch mutations are useful to update or delete many nodes at once. The returned data only contains the count
of affected nodes.
Batch mutations are not triggering subscription events!
For updating many nodes, you can select the affected nodes using the where
argument, while you specify the new values with data
. All nodes will be updated to the same value.
Set the published
fields of all unpublished Post
nodes that were created in 2017 to true
:
mutation {
updateManyPosts(
where: { createdAt_gte: "2017", createdAt_lt: "2018", published: false }
data: { published: true }
) {
count
}
}
Delete all unpublished Post
nodes where the name
of the author
is Alice
:
mutation {
deleteManyPosts(where: { published: false, author: { name: "Alice" } }) {
count
}
}