Skip to main content
GraphQL Basics
CHAPTER 09 Beginner

GraphQL Mutations

Updated: May 13, 2026
20 min read

# CHAPTER 9

GraphQL Mutations

1. Introduction

While Queries are used to read data, Mutations are used to write data. If you are familiar with REST APIs, Queries map to GET requests, while Mutations encompass POST, PUT, PATCH, and DELETE requests. In this chapter, we will explore the structure of a Mutation, how to handle create, update, and delete operations, and why returning data from a mutation is a best practice.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the conceptual difference between Queries and Mutations.
  • Write Mutations for creating, updating, and deleting data (CRUD operations).
  • Understand how mutations execute sequentially on the server.
  • Request updated data in the response payload of a mutation.

3. Beginner-Friendly Explanation

Imagine a banking app. When you want to check your account balance, you look at the screen. You are just *reading* information. In GraphQL, this is a Query. When you want to transfer money to a friend, you are changing the state of the bank. You are *modifying* data. In GraphQL, this is a Mutation.

A Mutation is essentially a Query that is allowed to cause side-effects. It takes data from the client, saves it to the database, and then immediately asks, "Okay, the data is saved, what information do you want me to send back to you?"

4. Real-World Examples

  • Creating Data: Submitting a sign-up form creates a new User in the database.
  • Updating Data: Clicking the "Like" button on a post increments the like count in the database.
  • Deleting Data: Clicking the trash can icon on a shopping cart item removes the item from the database.

5. Detailed Code Examples

Let's define a schema that supports CRUD operations for a Task management app.

The Schema:

graphql
12345678910111213141516
type Task {
  id: ID!
  title: String!
  isCompleted: Boolean!
}

type Mutation {
  # Create
  createTask(title: String!): Task
  
  # Update
  toggleTaskStatus(id: ID!, isCompleted: Boolean!): Task
  
  # Delete
  deleteTask(id: ID!): Boolean
}

6. Query Examples (Execution)

Here is how the client executes the Mutations defined above. Notice how we always ask for data back!

1. Create Operation:

graphql
1234567
mutation AddNewTask($title: String!) {
  createTask(title: $title) {
    id
    title
    isCompleted
  }
}

2. Update Operation:

graphql
123456
mutation MarkTaskDone($taskId: ID!) {
  toggleTaskStatus(id: $taskId, isCompleted: true) {
    id
    isCompleted
  }
}

3. Delete Operation: Instead of returning a Task object (since it no longer exists), delete operations commonly return a Boolean or a custom payload indicating success.

graphql
123
mutation RemoveTask($taskId: ID!) {
  deleteTask(id: $taskId)
}

7. Mutation Responses and UI Updates

Why do we ask for data back in a mutation? When you create a new Task on the frontend, the frontend doesn't know what database id was assigned to it. By requesting the id in the mutation response, the frontend can instantly add the new task to the UI and know its exact ID for future updates, without having to run a separate "fetch all tasks" query.

8. Multiple Mutations Sequence

You can send multiple mutations in a single request. Crucial Concept: While Queries execute in *parallel* (simultaneously) for speed, Mutations execute in *series* (one after another) to prevent race conditions.
graphql
1234567
mutation {
  # This executes first
  createTask(title: "First Task") { id }
  
  # This waits for the first to finish, then executes
  createTask(title: "Second Task") { id }
}

9. Best Practices

  • Return the Modified Object: Always return the object that was just created or updated. This keeps the client's cache (like Apollo Client) perfectly in sync with the server.
  • Use Specific Names: Instead of a generic updateTask mutation, consider intent-based names like markTaskCompleted or changeTaskTitle. This clarifies business logic.
  • Use Input Types for Large Updates: As learned in the previous chapter, if you are updating a user profile with 10 different fields, wrap them in an input UserProfileUpdateInput type.

10. Common Mistakes

  • Forgetting the Selection Set: Just like a Query, if a Mutation returns an Object Type (like Task), you must use curly braces {} to specify which fields of the Task you want returned.
  • Using Queries for Modifications: Technically, you *could* write database update logic inside a GraphQL query. This is a massive anti-pattern. Queries should be strictly read-only.

11. Mini Exercises

  1. 1. If a mutation creates a new user, what scalar field should it absolutely return in its selection set? (Hint: The database generates it).
  1. 2. Look at this schema: deleteUser(id: ID!): Boolean. Does the client need to use curly braces {} when calling this mutation?

12. Coding Challenges

Challenge 1: Write a Mutation operation that updates a user's email. Call the mutation UpdateEmail. It should use two variables: $id and $newEmail. Call the updateUser field and request the email and updatedAt fields in the response.

13. MCQs with Answers

Question 1

What is the fundamental difference in execution behavior between Queries and Mutations?

Question 2

Why is it a best practice to return the modified object from a mutation?

Question 3

Which REST HTTP method is most conceptually similar to a GraphQL Mutation?

14. Interview Questions

  • Q: Explain why GraphQL enforces that multiple mutations in a single request execute sequentially rather than in parallel.
  • Q: How should a delete mutation be structured in terms of its return type?
  • Q: Is there any technical difference in how the server processes the payload of a Query vs a Mutation, or is it just a naming convention?

15. FAQs

Q: Can I run a Query and a Mutation in the exact same request? A: No. A single request must be defined as either a query operation or a mutation operation at the root level.

Q: What happens if one mutation fails in a sequential list of mutations? A: Usually, the server will process the mutations up until the failure. The failed mutation will return an error in the errors array, and subsequent mutations in the list will not execute.

16. Summary

In this chapter, we tackled modifying data using Mutations. We learned that Mutations are designed for CRUD operations (Create, Update, Delete). We discovered the best practice of returning the updated object in the selection set so the frontend can keep its UI synchronized. We also learned a critical architectural rule: while queries run simultaneously, mutations run one by one to ensure data integrity.

17. Next Chapter Recommendation

We know how to design schemas, ask for data, and modify data. But how does the server actually get the data from the MySQL database when a query comes in? Proceed to Chapter 10: GraphQL Resolvers Explained to uncover the engine that powers GraphQL logic.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·