GraphQL API with Go: A Step-by-Step Tutorial for Beginners

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

Введение: Why GraphQL and Go are the Perfect Pair



Modern web development requires flexible and high-performance APIs. REST API, despite its popularity, often suffers from over-fetching or under-fetching of data. GraphQL solves this problem by allowing the client to request exactly what is needed. And Go (Golang) with its speed, simplicity, and built-in concurrency support becomes the ideal language for building GraphQL servers.



In this tutorial, we will step by step create a full-featured GraphQL API in Go. You will learn how to set up a server, define a schema, write resolvers, and implement queries and mutations. By the end of the article, you will have a working API ready for integration with any client.



Step 1: Project Setup and Dependency Installation



First, let's create a new Go module and install the necessary libraries. We will use two popular GraphQL libraries: graphql-go and graphql-go-handler.



1.1. Module Initialization



go mod init graphql-tutorial


1.2. Library Installation



go get github.com/graphql-go/graphqlgo get github.com/graphql-go/handler


These libraries provide all the necessary tools for working with schemas, types, and resolvers.



Step 2: Creating a Basic GraphQL Schema



The schema is the heart of a GraphQL API. It defines what data can be retrieved and what actions can be performed. Let's start with a simple "User" model.



2.1. Defining the User Type



import "github.com/graphql-go/graphql"

var userType = graphql.NewObject(graphql.ObjectConfig{ Name: "User", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.Int, }, "name": &graphql.Field{ Type: graphql.String, }, "email": &graphql.Field{ Type: graphql.String, }, },})


2.2. Creating the Root Query



var rootQuery = graphql.NewObject(graphql.ObjectConfig{    Name: "RootQuery",    Fields: graphql.Fields{        "user": &graphql.Field{            Type: userType,            Args: graphql.FieldConfigArgument{                "id": &graphql.ArgumentConfig{                    Type: graphql.Int,                },            },            Resolve: func(p graphql.ResolveParams) (interface{}, error) {                id, _ := p.Args["id"].(int)                // Here will be the logic for getting the user from the DB                return getUserByID(id), nil            },        },    },})


2.3. Combining into a Schema



var schema, _ = graphql.NewSchema(graphql.SchemaConfig{    Query: rootQuery,})


Step 3: Implementing Resolvers and the Server



Now that the schema is ready, we need to write resolvers — functions that actually return data. For simplicity, we'll use an in-memory store.



3.1. In-memory Store



type User struct {    ID    int    `json:"id"`    Name  string `json:"name"`    Email string `json:"email"`}

var users = []User{ {ID: 1, Name: "Ivan Petrov", Email: "ivan@example.com"}, {ID: 2, Name: "Maria Sidorova", Email: "maria@example.com"},}

func getUserByID(id int) *User { for _, u := range users { if u.ID == id { return &u } } return nil}


3.2. Starting the HTTP Server



package main

import ( "fmt" "log" "net/http"

"github.com/graphql-go/handler")

func main() { h := handler.New(&handler.Config{ Schema: &schema, Pretty: true, GraphiQL: true, // Enable built-in IDE })

http.Handle("/graphql", h) fmt.Println("Server started on")

Blogs

Book Recommendations