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

3 Getting to Know graphql-go: A GraphQL Library for Go

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

Getting to Know graphql-go: A GraphQL Library for Go

GraphQL has revolutionized the way developers build APIs over the past few years. With its declarative approach and flexible queries, GraphQL has become a popular choice to replace REST, and the Go (Golang) ecosystem is no exception. One of the leading GraphQL implementations in Golang is graphql-go , a simple yet powerful library for building GraphQL servers.

In this article, I’ll cover what graphql-go is, why you should consider it when building APIs in Go, along with an implementation example, query simulations, and even a visualization of the GraphQL request flow using mermaid code.


What is graphql-go?

graphql-go is an open source library developed by the Go community, inspired by the primary GraphQL implementation in the JavaScript ecosystem (graphql-js). This library provides tools to define schemas, set up resolvers, and process GraphQL queries safely and quickly on a Go backend.

Some of the advantages of graphql-go:

  • Type-safe schema: The schema is defined explicitly using Go structs and field tags.
  • Simple resolvers: Resolver functions can access data easily, with support for context and arguments.
  • HTTP integration: A great fit for integrating directly with net/http.
  • Performance and scalability: Very fast and efficient, ideal for real-time and scale-up applications.
  • Middleware support: Easy to integrate with other Go middleware (e.g. logging, auth, tracer).

Why Choose graphql-go?

As engineers, choosing tools isn’t just about following trends — it’s about how well a tool supports our application’s needs, both now and going forward. Here are some reasons to choose graphql-go:

Criteriagraphql-goREST (using Gorilla Mux, etc.)
FlexibilityQueries can filter, sort, and aggregate all at once. Clients fetch only the data they need.Rigid responses and varying endpoints
TypingGo-based schema and resolvers are type-safe, ideal for strictly typed codebases.Generally not strict, depends on JSON
EcosystemMany complementary libraries (validation, auth, dataloader).More mature, plenty of examples.
Learning CurveChallenging at first, but well documented.Relatively easy, with many tutorials.
PerformanceFast! Used by large streaming companies, banks, and fintechs.Proven and reliable.

A Simple graphql-go API Implementation Example

We’ll practice building a simple GraphQL API for a library application. The endpoint can query a list of books and add new ones.

1. Installing the Dependency

shell
1go get github.com/graph-gophers/graphql-go
2go get github.com/graph-gophers/graphql-go/relay

2. Define the GraphQL Schema

Create a schema.graphql file:

graphql
 1type Book {
 2    id: ID!
 3    title: String!
 4    author: String!
 5}
 6
 7type Query {
 8    books: [Book!]!
 9}
10
11type Mutation {
12    createBook(title: String!, author: String!): Book!
13}

3. Map the Schema to Go Structs

Create a schema.go file:

go
 1package main
 2
 3import (
 4    "context"
 5    "github.com/graph-gophers/graphql-go"
 6)
 7
 8type Book struct {
 9    ID     graphql.ID
10    Title  string
11    Author string
12}
13
14type Resolver struct {
15    books []*Book
16}
17
18func (r *Resolver) Books(ctx context.Context) ([]*Book, error) {
19    return r.books, nil
20}
21
22type mutationResolver struct{ resolver *Resolver }
23
24func (m *mutationResolver) CreateBook(ctx context.Context, args struct{ Title, Author string }) (*Book, error) {
25    book := &Book{
26        ID:     graphql.ID(fmt.Sprintf("B%d", len(m.resolver.books)+1)),
27        Title:  args.Title,
28        Author: args.Author,
29    }
30    m.resolver.books = append(m.resolver.books, book)
31    return book, nil
32}

4. Initialize the Schema & Run the HTTP Server

Create a main.go file:

go
 1package main
 2
 3import (
 4    "fmt"
 5    "io/ioutil"
 6    "log"
 7    "net/http"
 8
 9    "github.com/graph-gophers/graphql-go"
10    "github.com/graph-gophers/graphql-go/relay"
11)
12
13func main() {
14    schemaBytes, err := ioutil.ReadFile("schema.graphql")
15    if err != nil {
16        log.Fatal(err)
17    }
18    resolver := &Resolver{books: []*Book{
19        {ID: "B1", Title: "Golang for Beginners", Author: "John Doe"},
20    }}
21    schema := graphql.MustParseSchema(string(schemaBytes), resolver)
22    http.Handle("/query", &relay.Handler{Schema: schema})
23
24    log.Println("connect to http://localhost:8080/query for GraphQL playground")
25    log.Fatal(http.ListenAndServe(":8080", nil))
26}

Query & Mutation Simulation

Let’s test the GraphQL API using tools like GraphQL Playground or curl:

Query the List of Books

graphql
1query {
2  books {
3    id
4    title
5    author
6  }
7}

Response:

json
 1{
 2  "data": {
 3    "books": [
 4      {
 5        "id": "B1",
 6        "title": "Golang for Beginners",
 7        "author": "John Doe"
 8      }
 9    ]
10  }
11}

Adding a New Book

graphql
1mutation {
2  createBook(title: "Machine Learning with Go", author: "Jane Smith") {
3    id
4    title
5    author
6  }
7}

Response:

json
1{
2  "data": {
3    "createBook": {
4      "id": "B2",
5      "title": "Machine Learning with Go",
6      "author": "Jane Smith"
7    }
8  }
9}


GraphQL Flow Diagram in graphql-go

The mermaid visualization below illustrates the GraphQL request flow on the server we just built:

MERMAID
flowchart TD
    A[Client] -- HTTP POST /query --> B[Go HTTP router]
    B -- kirim payload ke relay.Handler --> C[graphql-go ParseSchema]
    C -- Temukan Query / Mutation --> D[Resolver Function]
    D -- Akses Data (slice, DB, atau API) --> E[Tulis Response JSON]
    E -- Response JSON --> A

Development Tips and Best Practices

  1. Use Context for Auth and Tracing Note that every resolver receives a context.Context. Use it to inject user info (JWT claims), set timeouts, and monitor request traces.

  2. Test Resolvers Independently Since the schema and resolvers are separate, you can unit test each resolver (for example, by mocking data to a database).

  3. Middleware Integration Integrate with popular Go middleware, such as logging, rate limiters, and metrics.

  4. Schema-First or Code-First With graphql-go, you can start from a schema file (*.graphql) or generate the schema from Go structs. Choose whichever suits your team.


Conclusion

graphql-go brings flexibility, performance, and simplicity to building GraphQL APIs within the Go ecosystem. With a type-safe schema, easy mapping between structs and the schema, and smooth integration with HTTP and middleware, this library is a great fit for modern microservices and real-time backends.

If you need a flexible and powerful API, consider graphql-go as the foundation for your next API layer. Learn and explore further in the graphql-go repository, and build a scalable API for the future!


References:

Related Articles

💬 Comments