GraphQL API with Go: Step-by-Step Practical Tutorial

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction

GraphQL is a modern query language for APIs, developed by Facebook. Unlike REST, it allows the client to request only the necessary data, which reduces network load and speeds up development. In this tutorial, we will create a full-fledged GraphQL API in Go (Golang) using the popular gqlgen library. You will learn how to set up a server, define a schema, write resolvers, and execute queries. The article is aimed at developers familiar with Go basics, but even beginners can follow the steps thanks to detailed comments.



1. Project Setup and Dependency Installation

First, let's create a new Go project and install the necessary packages.



Step 1: Module Initialization

mkdir graphql-go-tutorialcd graphql-go-tutorialgo mod init graphql-go-tutorial


Step 2: Installing gqlgen

gqlgen is a GraphQL code generator for Go. It automatically creates resolvers based on the schema.

go get github.com/99designs/gqlgen@latest


Step 3: Generating the Project Skeleton

Run the initialization command:

go run github.com/99designs/gqlgen init

After execution, you will see the structure:

  • graph/ — folder with schema and resolvers
  • server.go — entry point
  • gqlgen.yml — generator configuration


2. Defining the GraphQL Schema

The schema describes the data types and API operations. Open the file graph/schema.graphqls and replace its contents with the following:

type User {  id: ID!  name: String!  email: String!  age: Int!}

type Query { users: [User!]! user(id: ID!): User}

type Mutation { createUser(name: String!, email: String!, age: Int!): User! updateUser(id: ID!, name: String, email: String, age: Int): User deleteUser(id: ID!): Boolean}

Here we defined:

  • User — an object with fields id, name, email, age.
  • Query — read operations (get all users or one by ID).
  • Mutation — write operations (create, update, delete).

After saving, run the code generation:

go run github.com/99designs/gqlgen generate

This will create the files models_gen.go (Go types) and generated.go (resolver interfaces).



3. Implementing Resolvers and Data Storage

Now we need to write the logic for handling requests. For simplicity, we will store data in memory (a slice of structs).



Step 1: Create the Storage

Create the file graph/store.go:

package graph

import "sync"

type Store struct { mu sync.RWMutex users []User nextID int}

func NewStore() *Store { return &Store{ users: []User{ {ID: "1", Name: "Alice", Email: "alice@example.com", Age: 30}, {ID: "2", Name: "Bob", Email: "bob@example.com", Age: 25}, }, nextID: 3, }}

func (s *Store) GetUsers() []User { s.mu.RLock() defer s.mu.RUnlock() return s.users}

func (s *Store) GetUser(id string) *User { s.mu.RLock() defer s.mu.RUnlock() for _, u := range s.users { if u.ID == id { return &u } } return nil}

func (s *Store) CreateUser(name, email string, age int) User { s.mu.Lock() defer s.mu.Unlock() user := User{ ID: fmt.Sprintf("%d", s.nextID), Name: name, Email: email, Age: age, } s.nextID++ s.users = append(s.users, user) return user}

func (s *Store) UpdateUser(id string, name, email *string, age *int) *User { s.mu.Lock() defer s.mu.Unlock() for i, u := range s.users { if u.ID == id { if name != nil { s.users[i].Name = *name } if email

Blogs

Book Recommendations