101 What Is gqlgen? GraphQL Code Generation for Go
101 What Is gqlgen? GraphQL Code Generation for Go
Ever since GraphQL
emerged as an alternative to REST APIs, many developers have come to appreciate how easy it makes managing complex data efficiently. However, implementing GraphQL in Go was once a challenge of its own—especially when it came to type safety and writing the rather exhausting amount of boilerplate. It was precisely this problem that gqlgen was born to solve.
This article will cover what gqlgen is, why you should use it, and how to get started. Let’s dig deeper into ‘GraphQL Code Generation’ for Go, complete with code examples, flow simulations, tables, and diagrams. Ready? Let’s dive!
What Is gqlgen?
gqlgen is an open source framework library for building GraphQL servers in Go. Unlike other approaches that are usually code-first (defining the schema from code), gqlgen takes a schema-first approach—meaning you define your GraphQL schema using a .graphql file, and gqlgen will generate the Go code for you.
With this code generation strategy, gqlgen provides:
- Type Safety — All GraphQL operations are wired directly to Go models.
- Minimal Boilerplate — Resolver handler functions are generated automatically.
- Easy Integration — Support for middleware, directives, and custom scalars.
- Simple to get started — Straightforward configuration, reset with a single command.
Why Use gqlgen?
Let’s look at the table below for a comparison with other alternatives:
| Library | Approach | Type Safety | Code Automation | Popularity |
|---|---|---|---|---|
| gqlgen | Schema-first | ✔️ | ✔️ | ⭐⭐⭐⭐⭐ |
| graphql-go | Code-first | ❌ | ❌ | ⭐⭐⭐ |
| ent+entgql | Code/schema | ✔️ | Partial | ⭐⭐⭐⭐ |
The main advantage of gqlgen is that the generated code matches the schema, so when you refactor the schema you don’t have to worry about stale code being left behind—just regenerate.
gqlgen Architecture and Flow
Before moving on, let’s understand the simple flow diagram below using mermaid:
flowchart TD
A[Schema.graphql] -->|gqlgen generate| B[Resolver Stubs]
B --> C[Kode Go]
C --> D[API GraphQL Siap Digunakan]
- You write the schema in
schema.graphql. - The
gqlgen generatecommand produces Go code and a “stub” for each resolver. - You fill in the resolver functions according to your business needs.
- The GraphQL API server is ready to use.
Case Study: Building a Simple Book Store API
The following steps will guide you through building a simple API for a list of books.
1. Initialize the Project
Create a folder, initialize a Go module, and install gqlgen:
1mkdir bookapi-gql && cd bookapi-gql
2go mod init bookapi-gql
3go get github.com/99designs/gqlgenInitialize the gqlgen project structure:
1go run github.com/99designs/gqlgen initSeveral important files will be created:
schema.graphqlsresolver.gogenerated.go, and so on.
2. Define the Schema
Edit schema.graphqls:
1type Book {
2 id: ID!
3 title: String!
4 author: String!
5}
6
7type Query {
8 books: [Book!]!
9 book(id: ID!): Book
10}
11
12type Mutation {
13 addBook(title: String!, author: String!): Book!
14}3. Generate the Code
Run:
1go run github.com/99designs/gqlgen generateThis will generate stub handlers in resolver.go, models in model/models_gen.go, and other GraphQL code.
4. Complete the Resolver
Edit resolver.go
1package graph
2
3import (
4 "bookapi-gql/graph/model"
5 "context"
6 "strconv"
7)
8
9// In-memory database simulation
10var books = []*model.Book{
11 {ID: "1", Title: "Clean Code", Author: "Robert C. Martin"},
12 {ID: "2", Title: "The Pragmatic Programmer", Author: "Andy Hunt"},
13}
14
15// Query Resolver Implementation
16func (r *queryResolver) Books(ctx context.Context) ([]*model.Book, error) {
17 return books, nil
18}
19
20func (r *queryResolver) Book(ctx context.Context, id string) (*model.Book, error) {
21 for _, book := range books {
22 if book.ID == id {
23 return book, nil
24 }
25 }
26 return nil, nil
27}
28
29// Mutation Resolver Implementation
30func (r *mutationResolver) AddBook(ctx context.Context, title string, author string) (*model.Book, error) {
31 id := strconv.Itoa(len(books) + 1)
32 book := &model.Book{ID: id, Title: title, Author: author}
33 books = append(books, book)
34 return book, nil
35}5. Configure the Server
The starter server.go file usually already exists:
1package main
2
3import (
4 "log"
5 "net/http"
6 "os"
7
8 "bookapi-gql/graph"
9 "bookapi-gql/graph/generated"
10
11 "github.com/99designs/gqlgen/graphql/handler"
12 "github.com/99designs/gqlgen/graphql/playground"
13)
14
15func main() {
16 srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
17
18 http.Handle("/", playground.Handler("GraphQL playground", "/query"))
19 http.Handle("/query", srv)
20
21 log.Printf("connect to http://localhost:8080/ for GraphQL playground")
22 log.Fatal(http.ListenAndServe(":8080", nil))
23}Run the server:
1go run .Operation Simulation
Using the Playground at http://localhost:8080/, try the following operations:
Query All Books
1query {
2 books {
3 id
4 title
5 author
6 }
7}Response:
1{
2 "data": {
3 "books": [
4 {"id": "1", "title": "Clean Code", "author": "Robert C. Martin"},
5 {"id": "2", "title": "The Pragmatic Programmer", "author": "Andy Hunt"}
6 ]
7 }
8}Mutation to Add a Book
1mutation {
2 addBook(title: "Go in Action", author: "William Kennedy") {
3 id
4 title
5 author
6 }
7}Custom Scalars & Directives
One of gqlgen’s strengths is its support for custom scalars and directives. For example, suppose you want to use DateTime as a new scalar or control auth with a directive:
1scalar DateTime
2
3directive @auth(role: String) on FIELD_DEFINITIONConfigure it in Go and map it via the gqlgen.yml file—with full type safety!
Pros & Cons of gqlgen
| Pros | Cons | |
|---|---|---|
| Automation | Code always in sync with the schema | Schema changes → regenerate |
| Type Safety | Errors detected at compile-time | Learning schema-first |
| Performance | Nearly zero overhead, native Go types | Initial configuration is detailed |
| Community | Broad ecosystem, frequently updated | Documentation sometimes lags behind |
Conclusion
gqlgen is a game changer for Go developers who want to build GraphQL services without writing endless boilerplate. With its schema-first approach and type-safe code generation, you can focus on business logic and refactor the schema without worrying about a messy codebase.
References
#gqlgen #graphql #golang #backenddevelopment