Three Open-Source API Reference Alternatives
It all comes down to what you want to achieve with your API reference
What's the best way to automatically generate an API reference document? I've been building an API to help curate the API-related articles we report here every week. As the number of articles has been increasing it became clear that we needed help. So, I thought of creating an API that, given a URL, can generate a simple summary of any article. Even though this API is for personal consumption, I wanted to have its reference document automatically generated. Keep reading to find out how I did it.
This article is brought to you with the help of our supporter, Scalar.
Scalar is a suite of powerful & customizable developer tools to help you at all stages of API development. Create beautiful API Documentation in a notion-like editing experience.
I've been building an article summarization API using Node.js and Express.js. These are my personal preferences and are the tools that currently make me feel productive. I began by creating a YAML OpenAPI document and then crafting the operation that summarizes the content of an article. Since the root path (/
) was available I thought of using it to serve a JSON representation of the OpenAPI definition. This way, anyone requesting the root path receives the full OpenAPI definition. Since this API is for local use I didn't bother to think about authentication yet.
I also implemented content negotiation because I want the API to be available both as a machine-readable interface and also as a Web interface. With this approach, I can quickly create an HTML version of what the API offers that can be used directly from a browser. This approach opened the door to, among other things, quickly putting together a bookmarklet that summarizes the Web page you're looking at. This approach also made me think of providing a human-readable representation of the OpenAPI definition.
Following the content negotiation approach I implemented two alternative responses to the root path. Whenever the requesters accept a JSON response they'll get an OpenAPI JSON document. Whenever they accept HTML they'll get a human-readable Web interface of the OpenAPI reference. And, this is where I started having doubts about what to choose to render the OpenAPI reference.
Firstly, I wanted to use something open-source, and not a hosted solution—at least not for now. Then, I wanted something that could work well with my choice of tools: Node.js and Express.js. I wanted it to dynamically generate the HTML API reference and I wanted it to be easy to integrate, access, and use. I also wanted it to support recent versions of the OpenAPI specification and to provide example client code snippets. While at this point I'm not exposing the API to the public, I want to start with something that can give me room to expand if I want to.
With my list of soft requirements I searched for existing open-source OpenAPI reference tools and I came up with a short list of three solutions that I thought were worth more investigation:
Redoc: Built by Redocly, this is their open-source offering. I'm using redoc-express middleware to implement my API reference.
Scalar API Reference: Provided as open-source by Scalar1. I'm using the @scalar/express-api-reference module to attach the solution to my API implementation.
Swagger UI: Probably one of the oldest open-source solutions, supported by SmartBear. To make it work I used the swagger-ui-express module.
I must say that I was impressed because all three solutions were quite easy to configure and use with my Express.js setup. However, each one had their own intricacies. Let's start with Redoc to see how you could use it with your API. The Redoc solution is interesting because it generates the whole reference at runtime. In fact, the HTML of a Redoc reference Website consists only of a reference to the OpenAPI definition and a JavaScript tag. Everything runs in the browser. That also means you need to have your OpenAPI definition document available on a URL. Which I did. As I shared before, my root path is responding with a full OpenAPI JSON document, so I'm lucky. This is what the HTML source of my Redoc page looks like:
<html>
<body>
<redoc spec-url="/"></redoc>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js
</script>
</body>
</html>
There's a redoc
tag that defines the URL—in my case a relative one—of the OpenAPI JSON document, and then there's a JavaScript tag that loads the whole Redoc engine. In my case, I didn't install the JavaScript file locally but that can still be an option. The result of rendering this on the browser is quite good. Here's what the above-the-fold content looks like:
Most of the features I wanted were there. The only elements that I'm missing are examples of how to use the API. Even better would be to have a way to make requests directly from the reference document. Let's see what the next solution on my list, the Scalar API Reference, looks like. Scalar's solution follows a similar approach to Redoc in the way it renders the final output. It uses its own JavaScript file, in their case https://cdn.jsdelivr.net/npm/@scalar/api-reference
to do all the heavy lifting. However, in this case, the OpenAPI definition is embedded into the HTML itself. That means you don't need to have an OpenAPI JSON document available at a URL. This is what the relevant part of the HTML file looks like:
<script
id="api-reference"
type="application/json"
data-configuration="__HTML_ENCODED_JSON__">
__JSON__
</script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
Something that caught my curiosity was the script type being application/json
. That makes sense because the content of the script
tag itself is the full OpenAPI JSON document. What wasn't so clear to me was why the data-configuration
attribute holds an HTML-encoded version of my OpenAPI JSON definition. My guess is that it's used as a backward-compatible measure in case you try to access it with an older browser. Anyway, this is the look of the above-the-fold content for my OpenAPI reference:
What I found interesting here was the ability to easily obtain client code in multiple languages. Not only that but there's also an option that lets you make requests to the API right from the browser.
This is a great option because you don't have to leave the reference document to be able to see how the API works. Let's now see the final solution on my list, Swagger UI. The approach is very similar to the previous tools. In this case, though, the whole API definition is loaded into a JavaScript file that is responsible for initializing the rendering system. Unlike the other solutions, all JavaScript files are loaded locally, so you don't even need to be connected to the Internet to use Swagger UI. The relevant part of the HTML that renders the reference looks like this:
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>
<script src="./swagger-ui-init.js"> </script>|
It looks extremely simple. The first two scripts are responsible for configuring and setting up the whole rendering, and the last one loads the OpenAPI JSON definition. Here's what the rendering looks like above the fold:
While the look and feel isn't as polished as the two other solutions, once you open one of the operations you can see its full power.
You can even make a request right from the browser, in a similar way to Scalar.
What's missing here is the option to generate code snippets in different programming languages. However, the support for different OpenAPI elements feels more complete than the other solutions. As an example, Swagger UI supports the application/problems+json
content type for showing examples.
In the end, it all comes down to what you want to achieve with your API reference. These three solutions give you enough options to choose from. Nevertheless, you should pick the one that's mostly aligned with what you expect your users to achieve. I already picked the one I like the most. Can you guess which one it is?
Disclaimer: Scalar, one of the API reference solutions mentioned in this article, is a sponsor of the API Changelog newsletter.