What It Means to Be OpenAPI-First in Kubernetes
OpenAPI (previously known as Swagger) is a specification that initially provided developers the ability to document their REST APIs so users can easily understand what they offer and how to consume them. But because it is also a machine-readable specification, it has allowed for a boom of tooling around the specification and, as a result, around REST APIs.
OpenAPI Is Not Just About API Documentation
When developers are starting with their OpenAPI journey, they usually don’t realize that it can entail much more than just generating the documentation of the API. OpenAPI offers a modern way to build an API altogether that allows teams to acquire a lot of productivity and have a better development experience.
Let’s look at what these modern development workflows are and what they achieve.
Design-first is the process of designing and agreeing on an OpenAPI definition, and only after that each team can start working on writing the code to match the designed OpenAPI definition that now serves as an API contract.
Following this workflow will allow teams to have a more thoughtful discussion on what the API is going to look like (after all, we should think before we code, right?) and it allows different teams from the organization to be involved, such as consumer teams, legal, marketing, etc.
Tools like openapi-generator fit really well with the design-first approach, as API producers and consumers alike can generate boilerplate code from their OpenAPI definition for both servers and clients. There are also myriad testing tools that can use OpenAPI definitions to generate test skeletons to be used as a basis for testing functionality, performance and security.
Mocking tools can take an OpenAPI definition and generate mocked responses for the API automagically. With a design-first approach and mocking, frontend teams, for example, can start working on using the designed API without having to wait on the backend team, a great improvement in developer productivity.
Declarative Configurations for API Deployment
Eventually, an API will need to be deployed on infrastructure to make it available to consumers. In an environment that uses declarative configuration, developers define a configuration file that describes what the expected behavior of the system should be, and then some tools will reconcile the configuration with the system to match the expected behavior.
The Kubernetes project, and also tools like Terraform or Puppet, have vastly propelled the use of more and more declarative configurations through the use of YAML files. That’s because they’ve solved the issue of reconciling declarative configurations, which is a sophisticated solution in and of itself. So now developers can use these systems to deploy their applications and configure their environments.
This development pattern has allowed for methodologies like GitOps to rise: putting a declarative configuration in your GitHub repository and then using all the bells and whistles GitHub offers to deploy your application in a continuous way.
Ideally, you would be able to “GitOps your APIs,” but so far there hasn’t been an easy way to achieve that. The OpenAPI specification already offers a standard way to define APIs, but the Kubernetes ecosystem didn’t have first-class support for it. At least not yet.
Enter Kusk, an OpenAPI-first Gateway for Kubernetes
When the Kusk team at Kubeshop set out to bridge the gap between Kubernetes and OpenAPI, we thought of beginning to solve the problem from the entry point of APIs in Kubernetes: the gateway. Gateways or ingress controllers are what direct the traffic to different microservices depending on the request. For example, if a user makes a GET /cart request, the gateway should direct the request to the microservice that handles that specific path.
Having a gateway that can support OpenAPI was the first step to unlocking the power of the specification in the Kubernetes realm, but we didn’t find tools that really addressed it fully.
How Did Existing Gateways Support OpenAPI?
We wanted to look at how the popular gateways solved this issue. For instance, Kong’s support of OpenAPI is extremely cumbersome. To be able to configure Kong using OpenAPI, you need to convert the OpenAPI definition to a Kong-specific YAML definition by the use of Insomnia’s CLI and then use decK to convert that YAML definition to API calls that configured Kong through the Admin API. It was clear to us that OpenAPI was an afterthought in that case.
Other projects like KrakenD support some importing of OpenAPI, but developers still need to learn a specific configuration language to use KrakenD. Finally, Google’s Gateway had limited support for OpenAPI, and most of the configuration could only be done through Google Cloud’s GUI, REST API or Terraform.
Unfortunately for developers out there, none of the aforementioned gateways allow for a fluid and iterative development and deployment workflow for teams that have embraced an OpenAPI-first approach to building their APIs.
How Kusk Uses OpenAPI to Deploy Your APIs
Kusk is an open source OpenAPI-driven gateway for Kubernetes built by the team at Kubeshop. We wanted to take the benefits of the OpenAPI ecosystem and apply them to the Kubernetes world, and we were lucky to have Ole Lensmar, chairman of the OpenAPI specification for some years, to lead us.
When it came to using a gateway, we didn’t want to reinvent the wheel, as it is a very critical piece of software. We also wanted to have an open source solution and use open source all we could. We ended up choosing Envoy to power the gateway we were looking for. Envoy is a well-tested piece of software that has been used by many big projects in the Kubernetes world, although we knew we needed to simplify its configuration for developers.
With Kusk, the gateway is totally configured through OpenAPI. We use an
x-kusk annotation to extend the OpenAPI definition so developers can add the gateway-related configurations in a very simple way, like CORS rules, cache-control, rate-limit, OAuth and more directly to the OpenAPI definition. We then translate these annotations to Envoy-specific configuration, so we can abstract Envoy completely and let developers focus on the API only.
We didn’t want to be yet another gateway. We wanted developers to need only OpenAPI to configure all the aspects of the API, from the functional to the operational ones like configuring said gateway.
Because Kusk uses OpenAPI to configure Envoy, there are important features that can be unlocked from the gateway level, like automatically validating the requests with the fields defined in the OpenAPI definition, or even enabling gateway-level mocking of the APIs, and much more.
OpenAPI in Kubernetes, Finally
With Kusk, we wanted to tap into the power of the OpenAPI ecosystem fully. We expect developers not just to use the gateway itself, but to be able to use other tools from the OpenAPI ecosystem like documentation, code-generators, mocking and all the available tools and the ones to come from the power of the OpenAPI community.