Working with Mutations
Learn how to write and execute GraphQL mutations to create, update, and delete data.
What is a Mutation?
A mutation is a write operation that modifies data on the server. Mutations are similar to POST, PUT, PATCH, or DELETE requests in REST APIs.
Unlike queries, mutations:
- Modify data (create, update, delete)
- Require input objects to specify what to change
- Return the modified data so you can see the result
Basic Mutation Structure
Every GraphQL mutation follows this structure:
mutation MutationName($input: InputType!) {
mutationField(input: $input) {
returnedField {
subField
}
}
}
Simple Example
mutation CreateItem($input: ItemInput!) {
itemCreate(input: $input) {
item {
_id
title
}
}
}
Variables:
{
"input": {
"title": "New Item",
"price": 29.99
}
}
Mutation Types
Creating Resources
Mutations that create new resources typically follow the pattern resourceCreate:
mutation CreateCollection($input: CollectionInput!) {
collectionCreate(input: $input) {
collection {
_id
title
description
}
}
}
Variables:
{
"input": {
"title": "My Collection",
"description": "A new collection"
}
}
Updating Resources
Mutations that update existing resources typically follow the pattern resourceUpdate:
mutation UpdateItem($id: ID!, $input: ItemInput!) {
itemUpdate(id: $id, input: $input) {
item {
_id
title
price
}
}
}
Variables:
{
"id": "123",
"input": {
"title": "Updated Title",
"price": 39.99
}
}
Deleting Resources
Mutations that delete resources typically follow the pattern resourceDelete:
mutation DeleteItem($id: ID!) {
itemDelete(id: $id) {
success
message
}
}
Variables:
{
"id": "123"
}
Input Types
Mutations use input types to pass complex data. Input types are similar to regular types but are used only for input.
Understanding Input Types
input ItemInput {
title: String!
price: Float
description: String
tags: [String!]
}
Required vs Optional Fields
- Fields without
!are optional - Fields with
!are required
input ItemInput {
title: String! # Required
price: Float # Optional
description: String # Optional
}
Mutation Responses
Mutations return the modified data. Always select the fields you need from the response:
mutation CreateItem($input: ItemInput!) {
itemCreate(input: $input) {
item { # The created item
_id
title
price
}
errors { # Any validation errors
field
message
}
}
}
Common Response Patterns
Return the resource
mutation {
itemCreate(input: $input) {
item { _id title }
}
}
Return success status
mutation {
itemDelete(id: $id) {
success
message
}
}
Return errors
mutation {
itemCreate(input: $input) {
item { _id }
errors {
field
message
}
}
}
Using Variables
Always use variables for mutation inputs:
mutation CreateItem($input: ItemInput!) {
itemCreate(input: $input) {
item {
_id
title
}
}
}
Variables:
{
"input": {
"title": "New Item",
"price": 29.99,
"description": "Item description"
}
}
Partial Updates
For update mutations, you typically only need to include the fields you want to change:
mutation UpdateItem($id: ID!, $input: ItemInput!) {
itemUpdate(id: $id, input: $input) {
item {
_id
title
price
}
}
}
Variables (only update title):
{
"id": "123",
"input": {
"title": "Updated Title"
}
}
Multiple Mutations
You can execute multiple mutations in a single request, but they execute sequentially (not in parallel):
mutation {
first: itemCreate(input: $input1) {
item { _id title }
}
second: itemCreate(input: $input2) {
item { _id title }
}
}
Mutations execute in order, and if one fails, subsequent mutations may not execute.
Best Practices
- Always use variables - Use variables instead of hardcoding values to make mutations reusable and secure
- Request returned data - Always request the data you need from mutation responses (e.g., the created item) rather than just a success status
- Handle errors - Check for errors in mutation responses, including both GraphQL errors and validation errors. See Handling Errors for details
- Use descriptive names - Name mutations clearly (e.g.,
CreateUserProfileinstead ofMutation1) to help with debugging
Common Patterns
Create with Full Response
mutation CreateItem($input: ItemInput!) {
itemCreate(input: $input) {
item {
_id
title
price
description
createdAt
}
errors {
field
message
}
}
}
Update Specific Fields
mutation UpdateItemPrice($id: ID!, $price: Float!) {
itemUpdate(id: $id, input: { price: $price }) {
item {
_id
price
}
}
}
Delete with Confirmation
mutation DeleteItem($id: ID!) {
itemDelete(id: $id) {
success
message
}
}
Batch Operations
mutation CreateMultipleItems($inputs: [ItemInput!]!) {
item1: itemCreate(input: $inputs[0]) {
item { _id title }
}
item2: itemCreate(input: $inputs[1]) {
item { _id title }
}
}
Error Handling
Mutations can return errors in several ways:
GraphQL Errors
Errors in the errors array indicate problems with the mutation itself:
{
"data": null,
"errors": [
{
"message": "Unauthorized",
"extensions": {
"code": "UNAUTHORIZED"
}
}
]
}
Validation Errors
Some mutations return validation errors in the response:
{
"data": {
"itemCreate": {
"item": null,
"errors": [
{
"field": "price",
"message": "Price must be greater than 0"
}
]
}
}
}
Handling Both Types
Mutations can return errors in two ways:
- GraphQL errors in the
errorsarray (e.g.,UNAUTHORIZED,UNAUTHENTICATED) - Validation errors in the mutation response (e.g., field-level validation errors)
Always check for both types. See Handling Errors for detailed error handling patterns.
Common Mistakes
- Missing required fields - Ensure all required fields (marked with
!) are included in the input. The API will reject mutations with missing required fields - Not using variables - Avoid hardcoding values in mutations. Use variables to make mutations reusable and prevent security issues
- Not requesting returned data - Request the data you need from mutation responses (e.g., the created item) rather than just a success status
Summary
- Mutations are write operations that modify data
- Always use input types with variables
- Request returned data from mutation responses
- Handle errors (both GraphQL and validation errors)
- Use descriptive mutation names for debugging
Next Steps
- Working with Queries - Learn how to fetch data
- Paginating - Navigate through large datasets
- Filtering Data - Filter and sort your results
- Handling Errors - Understand error handling in detail