Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
19 Oct 2025 · 5 min read ·Article 111 / 125
Go

111 Adding a Mutation to the gqlgen Schema

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

111 Adding a Mutation to the gqlgen Schema

One of GraphQL’s great strengths lies in its flexibility and consistency when interacting with an API. In the Go backend world, gqlgen is a go-to framework that makes it easy for developers to build GraphQL schemas that are type-safe, fast, and easy to maintain. In this article, we’ll break down the process of adding a Mutation to a gqlgen schema, using a simple case study, sample code, and easy-to-follow explanations of the concepts.


What Is a Mutation in GraphQL?

Before diving into the code, it’s a good idea to understand this first: a mutation is the operation in GraphQL used to modify data (Create, Update, Delete), as opposed to a query, which is used only to read data.

Think of a mutation as the POST, PUT, PATCH, and DELETE of REST—but with the power and flexibility of GraphQL queries.


A Quick Look at gqlgen

gqlgen is a Go library that leverages generated code (code-first), ensuring that the GraphQL schema always stays in sync with your Go types. With just a little boilerplate, you can have a cutting-edge GraphQL API.


Case Study

Suppose we have a simple book catalog application. We want to be able to add a new book to the catalog through a GraphQL mutation.


Project Structure

Let’s assume the directories and files are laid out as follows (a standard gqlgen project):

text
 1project/
 2├── go.mod
 3├── gqlgen.yml
 4├── graph/
 5│   ├── model/
 6│   │   └── models_gen.go
 7│   ├── schema.graphqls
 8│   ├── resolver.go
 9│   └── schema.resolvers.go
10└── main.go

1. Defining the Mutation in the GraphQL Schema

The first step: open the schema.graphqls file. Here we’ll add a mutation for adding a book.

graphql
 1type Book {
 2  id: ID!
 3  title: String!
 4  author: String!
 5}
 6
 7input NewBook {
 8  title: String!
 9  author: String!
10}
11
12type Mutation {
13  addBook(input: NewBook!): Book!
14}

Explanation:

  • Book: The primary data type
  • NewBook: An input type—the data required to add a new book
  • addBook: The mutation we’re going to implement

2. Generating Code Automatically

Whenever the schema changes (for example, when the mutation above is added), run:

bash
1go run github.com/99designs/gqlgen generate

This command automatically:

  • updates models_gen.go (the Go structs derived from the GraphQL types),
  • updates the resolver interface in resolver.go and reminds us to fill in the function bodies.

3. Implementing the Mutation Resolver

Now open schema.resolvers.go and find the skeleton of the AddBook function.

go
1// graph/schema.resolvers.go
2
3func (r *mutationResolver) AddBook(ctx context.Context, input model.NewBook) (*model.Book, error) {
4    // TODO: implementation, e.g. save to an in-memory slice
5}

Here’s a simple example: store the data in a books slice held in the Resolver struct.

go
 1// graph/model/models_gen.go (auto-generated)
 2// type Book struct { ... }
 3// type NewBook struct { ... }
 4
 5// graph/resolver.go
 6
 7type Resolver struct {
 8    books []*model.Book
 9}
10
11// graph/schema.resolvers.go
12
13func (r *mutationResolver) AddBook(ctx context.Context, input model.NewBook) (*model.Book, error) {
14	newBook := &model.Book{
15		ID:     fmt.Sprintf("%d", len(r.books)+1),
16		Title:  input.Title,
17		Author: input.Author,
18	}
19	r.books = append(r.books, newBook)
20	return newBook, nil
21}

4. Simulating the GraphQL Mutation Query

Here’s an example mutation you’d typically run from the GraphQL playground or via curl:

graphql
1mutation {
2  addBook(input: { title: "Clean Code", author: "Robert C. Martin" }) {
3    id
4    title
5    author
6  }
7}

And the response:

json
1{
2  "data": {
3    "addBook": {
4      "id": "1",
5      "title": "Clean Code",
6      "author": "Robert C. Martin"
7    }
8  }
9}

5. Explaining the Workflow

To make things clearer, here’s a Mermaid diagram of the addBook mutation flow:

MERMAID
sequenceDiagram
    participant Client
    participant Server
    participant Resolver

    Client->>Server: send mutation addBook
    Server->>Resolver: panggil AddBook resolver
    Resolver-->>Server: return Book baru
    Server-->>Client: return response Book baru

6. Process Summary Table

StepFileExplanation
1. Defineschema.graphqlsDefine the Mutation and Input
2. Generatego run ... generateGenerate models & resolver
3. Implementschema.resolvers.goFill the AddBook resolver with Go
4. QueryPlayground/PostmanTry the addBook mutation
5. TestingAutomated/ManualConfirm the result is as expected

7. Tips & Best Practices

  • Be Explicit About Data Types: Use input types so the schema stays clear and scalable.
  • Error Handling: Always handle errors in the resolver.
  • Persistence: For production, store data in a database, not just a slice.
  • Authorization: Mutations often require stricter authentication.
  • Scalability: Structure your codebase in a modular way so adding new mutations is easy.

8. Going Further: Middleware & Validation

A mutation is the initial foundation, but validation checks (for example, requiring a unique title) and the use of middleware such as authentication checks are essential for production.

For example, a simple validation in the resolver:

go
1for _, b := range r.books {
2    if b.Title == input.Title && b.Author == input.Author {
3        return nil, fmt.Errorf("book already exists")
4    }
5}

Conclusion

With just a few simple steps, we’ve successfully added a mutation to a gqlgen schema. gqlgen is very powerful and has a friendly learning curve for Go developers. Mutations in GraphQL are highly flexible: whether you want to create, update, or delete, they can be tailored to your application’s needs at any time simply by modifying the schema and the resolver.

If you want a more advanced application, add a database layer, authentication, and more complete error handling. But the core mutation concept you learned today will remain consistent across a wide range of use cases.

Happy experimenting! 🚀


References:


If you enjoyed this article or want to dig deeper into GraphQL + Go, feel free to leave a comment or share! 👋

Related Articles

💬 Comments