API first web services

Filed under Web APIs on February 05, 2020

Recently, it’s become apparent at work that we should probably have skeletons in place to make it easier to get a new AWS service up and running. At the moment, the HTTP framework of choice is Gin, which is a nice enough framework that provides a familiar workflow:

  • Write your tests
  • Write your logic
  • Wire up your endpoints

Design First

However, while working elsewhere I was won around to the idea of Swagger first implementation of web services. At first I was skeptical, having come from the Spring boot world where you just slap a @Controller annotation on a class to make a new endpoint, and the spec first tools I’d used in the past in my own tinkering were a little meh to say the least.

At the time, we were generating our Swagger/OpenAPI files as part of our Maven builds, and that seemed to work pretty well, so why change it?

API Design first as Communication

The most important answer to that question is that I was working with other people.

Something that you only really learn if you pay attention is that you can generate full skeletons with an OpenAPI file, and this will ensure compatibility across your services. I could sit down and nut out the HTTP endpoints with another person, write the YAML, and send that to them to generate a mock on their end.

This patched up a lot of the cross-team communication problems we had, and allowed us to develop more independently of each other.

Testability

The other measurable improvement we saw was the testability of our code. Because all the wiring was done in a consistent way by the generated code, we were able to develop better testing patterns and get more coverage in our integration tests.

Taking this further with a framework like Goa, we can also split out our service logic completely for some nice, modular code with clear seperation of concerns.

Portability

Creating a Swagger file means that it becomes easier to port services to different languages if requirements change. If you can pick up your Swagger, generate a new skeleton in your new language, and deploy it quickly, it becomes easier to start strangling the old one and rerouting requests to endpoints with the confidence that your data contract won’t be broken.

Tools Available

The great thing about OpenAPI is that all major languages have a skeleton generator. OpenAPI Generator has an expansive list, with most of the languages and frameworks I’ve used showing up.

An alternative is to use a framework like Goa, which is the path I intend to head down with these skeletons. While not exactly OpenAPI first, it still allows a developer to specify the HTTP endpoints using their DSL. May not pan out for us, but hopefully if I do the heavy lifting around making sure it’s easy to do with a makefile, I should be able to shift the conversation away from individual tools to a larger system view.