Sometimes I do my best thinking in the car and today was an excellent example of this. I had a phone call today with a the digital agency Authentic who have been hired to help you stop saying Swagger, when you mean OpenApi. I’m only partially kidding. They asked me some hard questions about why I got involved in the OpenAPI Initiative, and experiences I have had with OpenAPI delivering value. Apparently this started a chain reaction of noodling in my subconscious because while driving my daughter to ballet, it hit me. I’ve been thinking about OpenAPI all wrong.
Let me be categorically clear. In the beginning, I was not a fan of Swagger. Or WADL, or RAML, or API Blueprint or RADL. I was, and largely still am, a card carrying Restafarian. I wear that slur with pride. I like to eat REST Pragmatists for breakfast. Out of band coupling is the scourge of the Internet. We’ve tried interface definition languages before. Remember WSDL? Been there, done that. Please, not again.
An Inflection Point
The first chink in my amour of objections appeared at the API Strategy Conference in Austin in November 2015 (There’s another one coming up soon in Portand https://apistrat.com/). I watched Tony Tam do a workshop on Swagger. Truth be told, I only attended to see what trouble I could cause. Turns out he showed a tool called Swagger-Inflector and I was captivated. Inflector used Swagger for a different purpose. It became a DSL for driving the routing of a Java based HTTP API.
An Inside Job
It wasn’t too long after that when I was asked if I would be interested in joining the OpenAPI Initiative. It was clear from fighting the hypermedia fight for more than 10 years, we were losing the war. The Swagger tooling provided value that developers building APIs wanted. Hypermedia wasn’t solving problems they were facing, it was a promise to solve problems that they might face in a few years by doing extra work up front. I understood the problems that Swagger/OpenAPI could cause, but I had a higher chance of convincing developers to stop drinking Mountain Dew than to pry a documentation generator from the hands of a dev with a deadline. If I were going to have any chance of having an impact, I was going to have to work from the inside.
A big part of my day job involves dealing with OpenAPI descriptions. Our customer’s import them, export them. My team uses it to describe our management API, as do all the other Azure teams. As the de-facto “OpenAPI Guy” at Microsoft I end up having a fair number of interactions with other teams about what works and what doesn’t work in OpenAPI. A re-occurring theme is people keep wanting to put stuff in OpenAPI that has no business in an OpenAPI description. At least that’s how I perceived it until today.
OpenApi descriptions are primarily used to drive consumer facing artifacts. HTML documentation and client libraries are the most prominent examples. Interface descriptions should not contain implementation details. But I keep running into scenarios where people want to add stuff that seems like it would be useful. Credentials, rate limiting details, transformations, caching, CORS… the list continues to grow. I’ve considered the need for a second description document that contains those details and augments the OpenAPI description. I’ve considered adding an “x-implementation” object to the OpenApi description. I’ve considered “x-impl-“ prefixes to distinguish between implementation details and the actual an interface description. But nothing has felt right. I didn’t know why. Now I do. It’s all implementation with some subset being the interface. Which subset depends on your perspective.
Pivot And Think Bigger
Remember Swagger-inflector? It didn’t use OpenAPI to describe the interface at all. It was purely an implementation artifact. You know why Restafarians get all uppity about OpenAPI? Because as an interface description language it encourages out of band coupling that makes independent evolvability hard. That thing that micro-services need so badly.
What if OpenAPI isn’t an interface definition language at all? What if it is purely a declarative description of an HTTP implementation? What if tooling allowed you to project some subset of the OpenAPI description to drive HTML documentation? And another subset could be used for client code generation? And a different subset for driving server routing, middleware, validation and language bindings. OpenAPI descriptions become a platform independent definition of all aspects of an HTTP API.
One of my original objections to OpenAPI descriptions is that they contained information that I didn’t think belonged in an interface description. Declaring a fixed subset of status codes an operation returned seemed unnecessary and restrictive. But for scaffolding servers, generating mock responses and ensuring consistency across APIs, having the needed status codes identified is definitely valuable.
For the hypermedia folks, their generated documentation would only be based on a projection of the link relations, media types, entry points and possibly schemas. For those who want a more traditional operation based documentation, that is fine too. It is the recognition of the projection step that is important. It allows us to ensure that private implementation details are not leaked to interface driven artifacts.
Back to Work
Now I’m sure many people already perceive OpenAPI descriptions this way. Well, where have you been my friends? We need you contributing to the Github repo. Me, I’m a bit slower and this only dawned on me today. But hopefully, this will help me find even more ways to deliver value to developers via OpenAPI descriptions.
The other possibility of course is that people think I’m just plain wrong and that OpenAPI really is the description of an interface.