Over the last 3 months, I have been involved on a project where I ended up building a GraphQL Server using Go. Before this, I had not worked on GraphQL before, on either frontend or backend. In this post, I would like to focus on two things: First, why I decided to use GraphQL over REST. And secondly, the Go Libraries that can help you build a graphql server from the grounds up.
This is going to be the first of a series of posts, in which am going to share my experiences on various aspects of building a GraphQL Server. I hope there will be at least three more posts with more technical details on how to solve and approach various issues that I came across.
Why I chose GraphQL?
The main reason, at least for me, was over fetching and under fetching. GraphQL allows the client to define exactly the data it needs from the server. The server will then return only that information. Let’s say a client needs a customer contact details, it will just get that and not more or less.
This is very difficult to achieve on REST, you will most likely end up returning related data on a request based on your best guess on what a client might need. Basically, contact details would also have other customer data that the client might not need at that specific time.
In simple terms, graphql allows you to treat your backend like a database that you can query for information you need and get exactly that.
Other reasons are:
Strongly Typed – graphql clients know exactly the data types to expect.
Acts as a single source of truth as proxy in front of your various end points or microservices.
Easy and Self Documentation, especially when combined GraphiQL. Updated automatically when you make changes.
GraphQL with Go– Which Library to use?
There are 4 main contenders for you to choose from, with each taking some sort of different approach to building GraphQL servers in go. Let’s have a brief look at them:
Disclaimer: I have only had first-hand experience with the first and the last of the libraries below, information on the other 3 is mostly from my research.
This is one of the most popular graphql library in this list. With this library, GraphQL types and schema are defined inside your go code. Well, this leads to a lot of boilerplate. You will notice that each of this library take a different approach on how you define schema and types creation. It was my first attempt at building a graphql server and worked very well.
The main reason why I switched to gqlgen, was that it doesn’t handle circular reference very well. And won’t event compile if there is one. There is a work around though which I didn’t find very intuitive for me, this may change in the future though.
Boilerplate aside, use this if you don’t mind your GraphQL schema and types definition living inside your go code. Here is a link to the GitHub repository.
This is one of the two schema first graphql libraries for go. Being schema first, simply means that you write your schema in schema definition language and have go parse it. As far as I can tell, it doesn’t use a generator or at least it’s not mandatory. This library aims to provide support for graphql draft specification with easy to use go APIs.
This is unlike any other library in this list, because it’s structs first and aimed to be a framework for rapid graphql server development. Being struct first means, you basically define your schema as structs, following all the rules of structs of exported fields. This will then generate resolvers automatically from Go struct types and function definitions. It also offers special go structs tags to give you more control on field names and which fields to skip.
One thing to keep in mind is that while it has been used in house production at samsarahq, it’s still in development and breaking changes may be introduced. Here is a link to the GitHub repository.
This is a schema first and type safe graphql library. Unlike graph-gophers/graphql-go from above, after writing your schema and types, you need to run the gqlgen code generator. The generator will then generate all necessary go files (boring bits) that you need to build your graphql server. The resolver file is only generated initially, but the models.go and generated.go files are regenerated every time to reflect your changes, and you shouldn’t edit them.
This allows you to bring over your schema from let’s say Apollo server and it will automatically generate all the resolvers for you. Then it’s a matter of writing resolver to your code. It is also very configurable, giving you options to re-use your models from the database, specify which struct tags to use, split up your schema files into multiple files etc. This configurations are placed inside a gqlgen.yaml file.
On top of that, Gqlgen is the most feature rich library in this list, as of the time of writing this. This is the library I ended up using and we are going focus more on it over the next few posts. Below, is a feature comparison from all four graphql libraries (it was created by gqlgen).
You can find the official documentation of gqlgen here.