Mar 03, 2019

The State of GraphQL × Go

I initially planned on writing this post to be about benchmarking and comparing implementations of GraphQL libraries and servers in Go vs. the popular JavaScript & Node.js alternatives like Apollo Server, etc. After delving into the Go ecosystem however, I've found myself switching between a couple of libraries, all having their set of advantages and drawbacks. Let's get into it.

To start off, the biggest GraphQL libraries and tools to simplify developing Go web applications are the codegen-based gqlgen, followed by the schema-based graph-gophers/graphql-go, runtime-type-based graphql-go/graphql and struct-based thunder. In addition to similar naming (not sure if this is a good thing), all of those present their own variety of awesome features, yet it seems that every single one is missing some traction to be fully suited for everyone's needs.

This observation seems especially valid if you look at the current issues of the aforementioned libraries: Whether gqlgen doesn't completely support gomodules yet, graph-gophers' library is missing distinct declarations for mutations and subscriptions (sitting on a seemingly stale PR) or graphql-go's implementation is relying way too much on loosely-typed empty interfaces (interface{}), which completely discards the benefits of type-safety.

Even if you combined all of the libraries' best features, they couldn't hold up to the current JavaScript-based tooling, especially not to the pace of new features being shipped. Although this is completely understandable since GraphQL has its biggest influence and impact in the direct web ecosystem surrounding JS, it's still a bit sad to me that the Go-based variants don't get as much love as they should.

If I had to choose between the mentioned libraries, because the graph-gophers implementation suits my needs and code style most, I'd go with that, even over the magnitude of gqlgen features. But if I had to choose the smartest solution, I'd decide to go the extra mile by building an extensive RPC/REST endpoint using built-in or popular Go tooling like Gin/mux/etc. and expose that using a Node.js-based GraphQL endpoint, effectively getting the best out of both worlds.

Maybe you've run into the same situation as me before, in that case, please let me know about any potential suggestions, because I really want to be able to build some GraphQL services in Go without having to hack together weird setups 👍