Prerequisites

Before you begin, ensure you have the following installed:

  • Go (version 1.16 or higher)
  • A code editor (like Visual Studio Code or GoLand)
  • Basic knowledge of Go and GraphQL concepts

Setting Up the Project

  1. Create a new directory for your project:
   mkdir go-graphql-example
   cd go-graphql-example
  1. Initialize a new Go module:
   go mod init go-graphql-example
  1. Install gqlgen:
   go get github.com/99designs/gqlgen
  1. Initialize gqlgen:

Run the following command to create the initial configuration and schema files:

   gqlgen init

This will generate several files, including gqlgen.yml, a GraphQL schema file (schema.graphqls), and a generated resolver file.

Defining the GraphQL Schema

Open the schema.graphqls file and define a simple schema for a User type and a query to fetch users:

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

type Query {
  users: [User!]!
}

This schema defines a User type with three fields and a users query that returns a list of users.

Implementing Resolvers

Next, we will implement the resolver for the users query. Open the resolver.go file generated by gqlgen and modify it as follows:

package graph

import (
    "context"
    "go-graphql-example/graph/model"
)

type Resolver struct{}

func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
    return []*model.User{
        {ID: "1", Name: "Alice", Email: "[email protected]"},
        {ID: "2", Name: "Bob", Email: "[email protected]"},
    }, nil
}

In this example, we return a static list of users. In a real application, you would typically fetch this data from a database.

Running the Server

Now that we have our schema and resolvers set up, we can run the server. Open the server.go file and ensure it looks like this:

package main

import (
    "log"
    "net/http"

    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/playground"
    "go-graphql-example/graph"
    "go-graphql-example/graph/generated"
)

func main() {
    srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    http.Handle("/", playground.Handler("GraphQL playground", "/query"))
    http.Handle("/query", srv)

    log.Println("Starting server on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

This code sets up an HTTP server that serves the GraphQL API and a GraphQL playground for testing.

Testing the API

To test the API, run the server:

go run server.go

Open your browser and navigate to http://localhost:8080. You should see the GraphQL playground. You can run the following query to fetch users:

query {
  users {
    id
    name
    email
  }
}

You should receive a response similar to this:

{
  "data": {
    "users": [
      {
        "id": "1",
        "name": "Alice",
        "email": "[email protected]"
      },
      {
        "id": "2",
        "name": "Bob",
        "email": "[email protected]"
      }
    ]
  }
}

Best Practices

  1. Use Structs for Models: Define your data models as structs in Go, which can be used for both GraphQL types and database models.
  1. Error Handling: Always handle errors gracefully in your resolvers and return meaningful messages to the clients.
  1. Pagination and Filtering: Implement pagination and filtering in your queries to handle large datasets efficiently.
  1. Use Middleware: Leverage middleware for authentication, logging, and error handling to keep your resolvers clean.
  1. Schema Versioning: As your API evolves, consider implementing schema versioning to maintain backward compatibility.

Conclusion

In this tutorial, we built a simple GraphQL API using Go and gqlgen. We defined a schema, implemented resolvers, and tested our API using the GraphQL playground. By following best practices, you can create robust and maintainable GraphQL APIs in Go.

Learn more with useful resources