Getting started with GraphQL + Golang (in 5 minutes)
A short straight guide on how to get things up and running with GraphQL in Golang
Requirements:
- Golang — i’m using version 1.13 at the time being;
Creating from scratch
Let’s start by creating a new directory and initialize a go module in it:
$ mkdir sample-graph
$ cd sample-graph// pseudo command: go mod init github.com/$owner/$repository
$ go mod init github.com/artemis-tech/sample-graph
go: creating new go.mod: module github.com/artemis-tech/sample-graph
GraphQL 101
First thing we’ll want to do is to describe how our GraphQL API will look like. That’s done by declaring a Schema, often a file named schema.graphql (i personally like to do so in a separate folder like graph/schema.graphql
):
where:
- scalar is the type of fields, which can be a custom, or basic types;
- schema is the root element on the GraphQL definitions, every query, mutation and subscriptions exists inside a schema;
- query, mutation and subscription types are sibling types and will stand for the endpoints we’ll provide with our API;
- object types have the only purpose of declaring what’s the structure of the data we want to deliver;
- input types are the exact opposite, their role is to declare how we want to receive data to our service.
The whole specification (all versions) can be found at: https://spec.graphql.org/
Generating code from Schema
All that said and done, there is one more step before getting hands on Go, we’ll need to generate some initial code based on schema.graphql so we don’t have to repeat the same definitions we did in it - there must be other tools but i’ve been happily using gqlgen for now:
// install gqlgen
$ go get github.com/99designs/gqlgen
Here is a simple default configuration for it (which i also like to have inside graph folder):
Then we have to run a command to auto-generate initial pieces of code:
// this will run the gqlgen generate command inside graph folder
$ (cd graph && go run github.com/99designs/gqlgen generate)// if graph folder was used, this is how it should look like
$ tree graph
graph
├── generated.go
├── gqlgen.yml
├── models_gen.go
├── resolver.go
└── schema.graphql0 directories, 5 files
Hands on code
Now finally, if you check graph/resolver.go
, it already has some code and GraphQL endpoints as methods, but all with a single line on it’s implementation:
panic("not implemented")
The initially generated resolver.go should look like this:
For us to be able to run this initially generated code we must create the entry point of our code, a dead-simple few-lined main.go file:
Although we have not yet implemented any query or mutation, we can already check the GraphQL Playground and receive the default message for unhandled errors:
Handling Errors
For panic("not implemented”)
to be treated as a GraphQL handled error, the gqlgen framework already expects it’s endpoints to return an errors.Error the second argument of it’s returns. For example:
By changing only that, we can already check a better experience taking place and how can we change the code to achieve the desired behavior on the GraphQL endpoints:
Resolving endpoints
As result of the auto-generating pieces of code we did earlier, we can see that the same types we defined in our schema are available as Go’s structs to be used on development. For example, if we want to implement our users storage as in-memory, we can define a global variable, which will be instantiated when the application starts (at main.go) and only exists while it’s running:
Then we can use the Users list (in-memory storage) when resolving our endpoints, for example:
The final version of this code will be available at GitHub, feel free to check:
Final thoughts
GraphQL is a powerful tool for the modern developer and can bring a lot of speed to development and reduce time-to-market. Just remember that like any other, researching if it’s the right tool for the job (there are a few use-cases here) and having a good balance between practical and theoretical knowledge will bring the most out of it.
Social
That’s it for this article, stay up to date with the news and knowledge we have to share on our networks: