Skip to content

Mutations in GraphQL — Complete Guide

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Mutations in Graphql. We cover key concepts, practical examples, and best practices to help you master this topic.

Mutations modify server-side data in GraphQL. Unlike queries that can run in parallel, mutations execute sequentially to prevent race conditions. Each mutation typically accepts an input type and returns a payload type.

What You'll Learn

  • Writing mutations for create, update, and delete operations
  • Input types and mutation payload conventions
  • Sequential execution guarantees
  • Optimistic UI update patterns

Why It Matters

Mutations are the only way to change data in GraphQL. Well-designed mutations reduce client complexity, provide clear return data for UI updates, and prevent common data integrity issues.

Real-World Use

GitHub's addReaction mutation returns the Reactable object so the client can update the UI without a follow-up query. Shopify's productCreate mutation returns the created Product and any user errors in a standardized format.

flowchart LR
    Client[Client] -->|Mutation| Server[GraphQL Server]
    Server --> Validate[Validate Input]
    Validate --> Mutate[Mutate Data]
    Mutate --> DB[(Database)]
    Server -->|Mutation Response| Client
    Note[Executed sequentially] -.- Server

Teacher Mindset

Design mutation responses to include the modified object so clients can update their local cache immediately. Return user errors in the payload rather than throwing exceptions for business rule violations.

Code Examples

# Example 1: Create mutation with input type
input CreateBookInput {
  title: String!
  authorId: ID!
  genre: Genre
  price: Float
}

type Mutation {
  createBook(input: CreateBookInput!): BookMutationResponse!
}

type BookMutationResponse {
  success: Boolean!
  message: String
  book: Book
  errors: [UserError!]
}
# Example 2: Update mutation
input UpdateBookInput {
  id: ID!
  title: String
  price: Float
}

type Mutation {
  updateBook(input: UpdateBookInput!): Book!
  deleteBook(id: ID!): Boolean!
}
# Example 3: Multiple mutations in one request
mutation OrderFlow {
  createCart(input: {userId: "1"}) {
    cart { id }
  }
  addItem(input: {cartId: "1", productId: "5", quantity: 2}) {
    cart { total }
  }
  checkout(input: {cartId: "1"}) {
    order { id status }
  }
}

Common Mistakes

  • Returning only the ID from a create mutation instead of the full object
  • Using union return types instead of a payload with user errors field
  • Making mutations idempotent when the operation type does not require it
  • Ignoring the sequential execution guarantee for related mutations
  • Not including the mutated data in the response for cache updates

Practice

  1. Write a createUser mutation with an input type for name and email.
  2. Design a mutation that updates a product price and returns the updated product.
  3. Write a delete mutation that returns a success boolean and a message.
  4. Create a mutation that adds an item to a cart and returns the updated cart.
  5. Challenge: Implement a mutation that creates an order from a cart in a single operation.

FAQ

Why do mutations execute sequentially?

Mutations modify state. Sequential execution prevents race conditions where the order of operations matters. Queries are read-only and can run in parallel.

Should I return the mutated object in the response?

Yes. Returning the mutated object lets clients update their caches without issuing a follow-up query.

What is the input type naming convention?

Input types are typically named with an Input suffix: CreateBookInput, UpdateBookInput. They group all arguments for a mutation.

How do I handle partial failures in mutations?

Return a payload with a success flag, the modified object, and a list of user errors. Clients check the errors field instead of relying on HTTP status codes.

Can I run mutations in parallel?

No. GraphQL guarantees serial mutation execution. If you need parallel writes, structure them as separate HTTP requests.

Mini Project

Add three mutations to your e-commerce schema: createProduct with input type, placeOrder that moves cart items to an order, and cancelOrder. Each mutation should return a payload with the affected object and user errors.

What's Next

Next, you will learn about subscriptions for real-time data streaming in GraphQL.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro