Thoughts on Web APIs
I have long history with web APIs. I’ve seen the industry oscillate between RPC and REST a few times now, including calling ad hoc JSON RPC APIs “REST”. At the end of the day I simply want an SDL1 for humans to describe an API that results in idiomatic, typesafe generated code.
Conceptually there was a lot of promise with SOAP and WSDL, but I don’t know anybody that ever enjoyed working with the generated client libraries. SOAP is also ostensibly tied to J2EE, which I suspect heavily colors its reputation for the worse.
Open API continues to fail the “usable by humans” test for me. It was not meant to be written by hand. If you don’t have a language and framework that can generate your schema for you, good luck.
There’s a lot to like about gRPC as its ecosystem spawns more browser friendly implementations (see: Connect Web and Twirp ), but it’s still an RPC framework that was built for server to server communication first, and the web client aspects feel bolted on. I wouldn’t fault anybody for using one of the above libraries to write an RPC layer in proto3 and expose it as a JSON API. It’s a pragmatic choice that should result in a productive development experience.
Which brings me to GraphQL, a schema and query language that meets the vast majority of my requirements. Its schema language is light on syntax, which makes it easy to read and write by humans. It has a rich and stable ecosystem with good tooling and code generation libraries. I think GraphiQL is the one of the absolute best things about the ecosystem, and provides an easy way for developers to explore a GraphQL API.
It isn’t all sparkles and unicorns though. Writing queries can become tedious, and for larger domain models they can get very large. The query language is also poorly suited to any highly nested data model. (Representing a comment thread with nested replies in GraphQL is really problematic.)
But at the end of the day GraphQL works well, allows you to use regular HTTP and JSON, handles all the boilerplate for you when needing statically typed client/server communication.
If you are using Go on the server and Typescript in the browser you can wave away almost all the tedium and boilerplate and focus on your domain logic.
For your server written in Go use gqlgen. It’s well documented, emphasizes schema first design, and generates idiomatic Go code. I found it easy enough to focus on writing resolver implementations and access the introspection utilities to optimize database use and mitigate N+1 issues.
For your web client library I found graphql-codegen to be a good choice, and it integrates well with almost all of the popular GraphQL client libraries.
I’m optimistic I’ll be able to keep GraphQL in my tool belt for quite some time. I’d certainly like to keep one aspect of software development low churn for awhile.
Schema Definition Language ↩