Mastering GraphQL Mutations: A Step-by-Step Guide for Beginners


GraphQL mutations allow clients to modify data on the server, such as creating, updating, or deleting records. Unlike queries, which fetch data, mutations are used to perform side effects on the server.
This article introduces basic mutations and explains how to handle input types in a GraphQL API.
What Are GraphQL Mutations?
In GraphQL, mutations allow you to:
Change data on the server.
Optionally return updated data as part of the response.
Example:
Here’s a basic mutation:
mutation {
createUser(input: {name: "Alice", age: 25}) {
id
name
age
}
}
This mutation:
Creates a user with the provided input fields (
name
andage
).Returns the newly created user’s data (
id
,name
, andage
).
Writing Basic Mutations
Step 1: Define the Schema
Define the mutation in the schema along with the required input type.
# schema.graphql
type User {
id: ID!
name: String!
age: Int
}
input CreateUserInput {
name: String!
age: Int!
}
type Mutation {
createUser(input: CreateUserInput!): User!
}
Explanation:
User
: Represents the user object returned after the mutation.CreateUserInput
: An input type defining the fields required to create a new user.Mutation
: The root type for all mutations. ThecreateUser
mutation accepts an input object and returns aUser
.
Step 2: Implement the Resolver
Create a resolver for the createUser
mutation.
package main
import (
"fmt"
"github.com/google/uuid"
)
type User struct {
ID string
Name string
Age int
}
var users = []*User{}
type mutationResolver struct{}
func (r *mutationResolver) CreateUser(input CreateUserInput) (*User, error) {
user := &User{
ID: uuid.NewString(), // Generate a unique ID
Name: input.Name,
Age: input.Age,
}
users = append(users, user) // Add the new user to the list
return user, nil
}
type CreateUserInput struct {
Name string
Age int
}
Explanation:
User Struct: Represents the
User
data type.Global User List: Simulates a database by storing users in memory.
UUID Generation: Generates a unique ID for each new user using
uuid.NewString()
.Resolver Logic:
Takes the input object (
CreateUserInput
).Creates a new user object.
Appends it to the
users
list.Returns the newly created user.
Step 3: Mutation Example
You can test the mutation with the following query in GraphQL Playground:
mutation {
createUser(input: {name: "Alice", age: 25}) {
id
name
age
}
}
Expected Output:
{
"data": {
"createUser": {
"id": "a1b2c3d4-e5f6-7890-ghij-klmnopqrst",
"name": "Alice",
"age": 25
}
}
}
Handling Input Types
Input types allow you to define structured data for mutations. Let’s dive into more details:
Step 1: Update the Schema for Input Types
We already defined the input type CreateUserInput
in the schema:
input CreateUserInput {
name: String!
age: Int!
}
Explanation:
Input Object: Defines the shape of data the mutation expects.
Mandatory Fields: The
!
ensuresname
andage
must be provided.
Step 2: Pass Input in Resolvers
The input type is automatically mapped to Go structs:
type CreateUserInput struct {
Name string
Age int
}
func (r *mutationResolver) CreateUser(input CreateUserInput) (*User, error) {
user := &User{
ID: uuid.NewString(),
Name: input.Name,
Age: input.Age,
}
users = append(users, user)
return user, nil
}
Explanation:
Struct Mapping: The
input
parameter matches theCreateUserInput
schema.Reusability: You can use the
CreateUserInput
struct in multiple resolvers.
Testing Additional Scenarios
Create Multiple Users:
mutation { createUser(input: {name: "Bob", age: 30}) { id name age } }
Query All Users (if supported):
query { users { id name age } }
Conclusion
This article explained:
How to write basic mutations.
How to define and handle input types for structured data.
GraphQL mutations provide a powerful way to modify server-side data while maintaining flexibility. By using input types, you can enforce structured inputs and reduce validation overhead. Start experimenting with these concepts to master creating efficient APIs!
Subscribe to my newsletter
Read articles from Shivam Dubey directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
