An Introduction to OpenAPI
4 use cases of OpenAPI which are good to know
In this article I offer an introduction to OpenAPI (OA) and some of its more interesting use cases. If you are already familiar with what OA is, you can skip ahead to the use-cases part of this article.
What is OpenAPI?
OpenAPI is a specification for documenting HTTP-based APIs in a way that allows users, usually from outside the team that works on the API itself, to understand the functionalities it exposes and interact with it.
The specification was originally developed by a company called SmartBear under the name “Swagger”, becoming the de facto standard for API documentation. This led to the formation of the OpenAPI initiative under the linux foundation, which now governs the specification, as well as the renaming of the specification from Swagger to OpenAPI. Thus, when you read about Swagger specs and OpenAPI specs these are practically the same — Swagger is simply the earlier versions (before version 3.x.x) of OpenAPI.
Creating Specs
OA specs usually take the form of YAML
file(s), although JSON
is also supported. You can see examples of specs in this repository, and also here.
Specs can be a single file — or multiple files with references ($ref
) that point to files or remote resources using a path. If you use refs, these can either be a relative/absolute file path or the URI of a resource on a network. This makes OA specs very elastic but also somewhat confusing at first — our minds are not well adjusted to parsing refs, and this makes the learning curve somewhat steeper. You can read more about this feature here.
The simplest way to create OA specs is to write down a .yml file or a bunch of them. This though couples the writing and maintenance of API specs to the development process, adding overhead. Furthermore, when specs are written by hand this inevitably leads to human error and situations where the specs are not synced with the actual API. As such this is a practice that should be avoided whenever possible — unless there is a compelling reason to do so.
The alternative is to generate OpenAPI specs from code.
Many newer backend frameworks have some degree of OA spec generation built-in. For example, FastAPI (Python) has spec generation as part of its core functionalities, and NestJS (TypeScript) has an optional core extension for it.
Older frameworks on the other hand, tend to have a rich ecosystem surrounding them, including libraries for generating OpenAPI specs. For example see: this library for Django+DRF (Python), this library for Spring Boot (Java/Kotlin), this library for Rails (Ruby), and this library for Laravel (PHP).
Validating Specs
The closer the OA specs creation is to the API code and the more typing information can be gleaned from the language used, the better you can trust the generated OA specs to reflect the API endpoint in question. Thus inversely, the more manual intervention there is, the less you can trust the specs.
It is therefore a good idea to test the specs against the actual API — especially if you have to manually write the specs or adjust the generation process. For some frameworks, there is a specialized library for this purpose, for example, see this library (which I co-authored) for Django+DRF, and there are more generalized testing solutions as well — see the testing and debugging use case at the end of the article for more details.
Another option is to validate that the specs are correctly written, lint for errors or check the style of the specs. If you are using a solid library to generate the specs for you this is probably redundant. On the other hand, if you write the specs by hand or modify them post-generation and commit them to your VCS, then this form of validation is required.
To this end, there is an official CLI tool you can install using NPM/Yarn. Its validation messages are quite bad and hard to understand — so it’s not the best linting tool. A more elegant tool is the openapi-cli, again using Node.js as a backbone. Unless you have a good reason to use the official CLI, I would recommend using this tool for this purpose.
TIP: it’s generally a best practice to validate your specs in CI and using pre-commit hooks.
Use Case: Documentation
The first and primary use of OA specs is, of course, to document an API. Documentation though is useless without a way of consuming it.
To this end, there are multiple tools that generate a UI for displaying API specs.
The oldest tool in this space is swagger-UI by SmartBear. Its free and straightforward to use, but its default UI and styling isn’t great in my opinion. Furthermore, it lacks a lot of the bells and whistles that the other tools discussed below have (e.g. advanced search functionalities). If you don’t mind having a rather basic website to display your specs, its a solid option.
Another very popular is called redoc, its maintained by the same company (which grew out of the open-source project) that maintains the openapi-cli
project, called Redocly. This tool offers a great-looking UI out of the box — using the CLI you can easily generate a production-ready React driven website that has good customization and a nice crispy look, an example of which you can see here. If you need a lot of branding or more complex functionalities, you will need to go the paid route though.
Finally, there is RapiDoc, which is an open-source project that offers a lot of options. It’s a framework agnostic JS library, so you can use it with with any framework you like (e.g. Vue, React, etc.). You also have complete control of styling, but can also use its great defaults. This is a more involved option, requiring development time, but it also offers more then the others in terms of customization and user control. Depending on your use case, this might be a good option.
Note: a lot of the libraries and frameworks mentioned in the previous section bundle at least one of these tools. Thus for example, FastAPI offers a redoc website out of the box, and DRF Spectacular comes with both Swagger-UI and redoc. You should therefore check this in advance and make decisions accordingly.
Use Case: Code Generation
Because OA specs are machine-readable and contain a lot of information about types, one of their primary use cases is code generation. You can do a lot with this — the common examples are generating client SDKs and server stubs from OA specs, creating reference clients, or even creating client scaffolding to be used in the application Frontend.
There are two very popular projects that dominate this space, both of which take a somewhat similar approach using templates for code-gen:
The first projet is Swagger Codegen, again by SmartBear. This project has 13K stars on Github and is very stable. Its uses though are somewhat more limited, as is the range of templates that it supports.
The second project, with 10K stars, is OpenAPI-Generator. This project offers a wide range of tools — written in Java — and a huge number of templates to choose from. It’s very powerful, and it has capabilities the other project does not, but is somewhat less stable (read, has breaking changes between versions).
Use Case: TypeScript
If your project includes a Frontend component developed using TypeScript, one of the most useful things you can do with OA specs is to generate TypeScript types from them. I’ve done this in multiple projects, including once by writing an OA to TypeScript converter myself. Luckily, these days there are two mature open-source generators that will do the work for you: DTSGenerator and openapi-typescript.
If your project has a development deployment, I recommend doing the following: expose an endpoint that allows downloading the OA specs as a file. Then create a shell script that downloads the specs using curl
or wget
, piping the result to one of these tools. For example, the following script uses DTSGenerator in such a fashion:
This way it becomes very easy for frontend developers to update the API specs — requiring only a short shell command.
You could alternatively publish the generated types as an internal NPM package, or install them from a repository. This though moves control from the frontend to the backend and is somewhat less elastic.
Use Case: Testing and Debugging
One interesting way of testing APIs, which is increasingly becoming more popular, is what’s known as “fuzz testing”. This is a form of Property Based Testing but for an API rather than a function. In Fuzz testing, a given API is tested against a range of randomized data, identifying weaknesses, unhandled errors, etc. Although the main purpose of Fuzz testing is to identify security and code weaknesses, it is also a way to ensure that OA documentation precisely reflects the API it represents.
There are paid services that use OA specs as a source of truth, for example, Gitlab has an offering for customers on its ultimate plan. But, there are also multiple open source solutions. Dredd is a mature, multiplatform project, which can be used for this purpose. And in the Python world, there is schemathesis, which builds on the excellent Hypothesis testing library to offer fuzz testing.
Conclusion
In this article I discussed OpenAPI and various aspects of it. The above was meant as a general introduction, while also offering use cases I find interesting and valuable. The OA ecosystem is dynamic and constantly growing. I recommend taking a look at this website for a comprehensive list of tools, as well as at this awesome list.