Automate API Documentation and TypeScript Types with OpenAPI

Recently, my assigned task was updating the API documentation on a project to OpenAPI format. The process of translating the old Markdown file to the proper YAML format felt somewhat tedious, begging the question, “Is this worth it?” However, once I started to dig into the uses of OpenAPI, I realized the numerous benefits far outweighed the upfront effort. If you are unfamiliar with the OpenAPI specification (FKA the Swagger Specification), here are some ideas on how to get started using it in your project.

What is OpenAPI Specification?

The OpenAPI Specification (OAS) is a specification for interface files used to describe RESTful web services as a JSON object (represented in either JSON or YAML format). According to swagger.io, OAS “allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection.” Essentially, it is a format for defining an API. Once your schema is in this format, you can leverage the numerous benefits of OAS, including code generation and documentation.

Why should you use it?

Once you have defined your API using OAS, you are ready to reap the benefits! Here are a couple of ways that defining our API using OAS benefits our project:

1) Code Generation

Using OAS allows you to auto-generate code in a multitude of languages. You can generate both client- and server-side code. If your project happens to use TypeScript, you can also auto-generate types based on your OpenAPI schema.

In our project, we use the openapi-typescript plugin to generate types based on our API. We use these auto-generated types to define the URL parameters, query parameters, request body, and response body for each endpoint.

For example, if you have an endpoint defined in OAS like so:


/{userId}/user:
  parameters:
    - name: cognitoId
      in: path
      required: true
      schema:
        type: string
  get:
    operationId: getUser
    responses:
      200:
        description: success
        content:
          application/json:
          schema:
            $ref: "#/components/schemas/UserInformation"
      404:
        description: user not found
        content:
          text/plain:
          schema:
            type: string

The generated file created by openapi-typescript will provide a schema. You can grab types from that schema to use in your project. From the endpoint described above, we can grab the following type from the generated schema to use in our code:


import { operations } from "./schema";

type GetUser = {
  UrlParams: operations["getUser"]["parameters"]["path"];
  ResponseBody:
    | operations["getUser"]["responses"]["200"]["content"]["application/json"]
    | operations["getUser"]["responses"]["404"]["content"]["application/json"];
};

Using generated types in this manner forces us to update the OAS file and regenerate types when we add or change an endpoint. Although this means extra work in the moment, it ensures that we keep our OAS file up to date.

2) Documentation

Having a well-defined OpenAPI schema also makes it easy to generate API documentation using online tools. Since external services use the API, we must have up-to-date documentation for other teams to reference.

In our project, we use Stoplight Elements to create interactive API reference documentation. This allows us to easily embed our OAS document in an HTML page published using Gitlab pages. So, anyone with access to the project repo can view (and interact with) the documentation. This page is regenerated and published each time we merge changes to our development branch to ensure our published documentation is always current.

Automating API Documentation and TypeScript Types with OpenAPI

These examples only cover a couple of use cases for the OpenAPI Specification. If you have an example of using OAS in a project, let me know in the comments!