Generate GraphQL Client Code With Go
Tags: go, graphql, gqlgen
Published: 2020-07-07 07:01:45

---
title: Generate GraphQL Client Code With Go
published: true
description: Created a command line tool to generate a client for GraphQL using based on gqlgen.
tags: Go, GraphQL, gqlgen
cover_image: https://www.pakutaso.com/shared/img/thumb/redstYT027_TP_V.jpg
---

Hi! I’m a Japanese software engineer with Go and Typescript.I develop applications every day when work and play. These days I use GraphQL a lot with them. And I use [Apollo](https://www.apollographql.com/), [GraphQL Code Generator](https://graphql-code-generator.com/) and [gqlgen](https://gqlgen.com/) for that. They are my favorite projects. They have in common that generate code.
So, I want to generate client for Go.
There are client for Go:
- [github.com/shurcooL/graphql](https://github.com/shurcooL/graphql)
- [github.com/machinebox/graphql](https://github.com/machinebox/graphql)

These libraries are very simple and easy to handle and used by [gqlgen](https://gqlgen.com/). But these don’t generate code. I want to generate code by response of introspection query from server. The [GraphQL Code Generator](https://graphql-code-generator.com/) have it. This user will have a comfortable development life.

So I give gopher and myself the same experience as a web client engineer.
I prepared for that.

{% github Yamashou/gqlgenc %}

## Installation

```bash
go get -u github.com/Yamashou/gqlgenc
```

## How to use

This is a client generator based on the gqlgen plugin. If you use it, choice CLI or a plugin. I will explain how to use it using the Github API. If you don’t read this sentence, read here.

### First, You create .gqlgenc.yaml in your project root.

```yaml
model:
  filename: ./gen/models_gen.go
client:
  filename: ./gen/client.go
models:
  Date:
    model: github.com/99designs/gqlgen/graphql.Time
endpoint:
  url: https://api.github.com/graphql
  headers:
    Authorization: "Bearer ${GITHUB_TOKEN}" # public access token
query:  
   - "./query/*.graphql"
```

If you don’t have a github token, you see here

### Next, You create query.graphql in /query. 

This query get your repositories.

```graphql
fragment LanguageFragment on Language {
    id
    name
}
query GetUser($repositoryFirst: Int!, $languageFirst: Int!) {
    viewer {
        id
        name
        repositories(first: $repositoryFirst, orderBy: {field: CREATED_AT, direction: DESC}) {
            nodes {
                id
                name
                languages(first: $languageFirst) {
                    nodes {
                        ...LanguageFragment
                    }
                }
            }
        }
    }
}
```

### Finally, You exec a command in your project root.

```bash
gqlgenc
```

Your client code is generated in /gen.
Then, run this code:

```go
package main

import (
	"context"
	"fmt"
	"github.com/Yamashou/gqlgenc/client"
	"github.com/Yamashou/gqlgenc/example/github/gen"
	"net/http"
	"os"
)

func main() {
	// This example only read public repository. You don't need to select scopes.
	token := os.Getenv("GITHUB_TOKEN")
	authHeader := func(req *http.Request) {
		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	}
	ctx := context.Background()
	githubClient := &gen.Client{
		Client: client.NewClient(http.DefaultClient, "https://api.github.com/graphql", authHeader),
	}
	getUser, err := githubClient.GetUser(ctx, 10, 10)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %s", err.Error())
		os.Exit(1)
	}
	fmt.Println(*getUser.Viewer.Name, getUser.Viewer.Repositories.Nodes[0].Name)
	for _, repository := range getUser.Viewer.Repositories.Nodes {
		fmt.Println(repository.Name)
		for _, language := range repository.Languages.Nodes {
			fmt.Println(language.Name)
		}
	}
}
```
https://github.com/Yamashou/gqlgenc/blob/master/example/github/main.go

To understand the example, you read this code, readme and [gqlgen](https://gqlgen.com/) document. If you understand Japanese, read here.

## Afterword
This article is my first post with English. You may have a sentence that don’t understand, but I’m very happy to have this challenge. Thank you for reading this to the end.