Vale & The OpenAPI Specification

A tutorial on linting your OpenAPI Specification files

OpenAPI Specification files provide machine-readable (JSON or YAML) descriptions of APIs and often contain snippets of text suitable for linting.

The problem is that the target text can be hard to reach from a linting perspective. For instance, consider the following basic example:

https://gist.github.com/jdkato/2485b467ab8470db244b23dc9b60b7c2

As you can see above, the only parts we’re really interested in are the , (which can contain Markdown), and keys.

In the following sections, we’ll discuss the three main techniques for linting specification files using Vale (an open-source linter for prose). For the examples, we’ll be referencing the file from Swagger.

Option 1: No Processing

https://gist.github.com/jdkato/dfc8c100c134b98ebeb7f074b6d29cc8

The easiest way to lint an OpenAPI specification file is to simply pass it, as is, to Vale:

Vale will treat the file as plain text and lint its content line by line, but you’ll likely receive a lot of meaningless errors related to the formatting syntax (JSON or YAML) and Vale won’t be able to correctly parse any embedded Markdown.

Option 2: Post-Processing

https://gist.github.com/jdkato/1967c2ea4edb37bc78b177b5fbd99cd4

The next option involves transforming your specification files after they’ve already been created.

This will (generally speaking) probably feel like the most “natural” solution as its methodology is quite similar to that of existing tools — for example, Swagger UI (transforms specs for presentation) and Swagger Codegen (transforms specs for consumption), etc.

Option 2a: Key Extraction

The most obvious solution is to extract and lint the desired keys individually.

Thanks to the machine-readable nature of the specification files, this can be done in a few lines of your favorite scripting language (such as Python, which we’re using below):

https://gist.github.com/jdkato/40211d9276845b2dad10fe2ba7987fc3

You can use this script by passing your spec as a parameter:

Option 2b (only OAS2): Swagger2Markup

Another option is to convert the entire specification into a format that Vale can understand (AsciiDoc or Markdown) using the Swagger2Markup library.

For example, you’d use the following command to lint the Petstore example:

Unfortunately, since Vale is linting our content outside of the actual specification file, both of these options don’t report meaningful file locations.

Option 3: Pre-Processing

https://gist.github.com/jdkato/9f71ac48ccf165dca5dc3d003ce0888d

Up to this point, all of our options focus on working with a specification file that already exists. This makes sense in a number of ways: it’s similar to how other OpenAPI tooling works, it makes no assumptions about where the specification information comes from, and it can be integrated into almost any existing workflow.

However, from a writing perspective, this workflow isn’t ideal: if you’re interested in linting your specification files, then you’re likely intending to edit those files too (i.e., you’d surely fix any errors found). The problem here is that the specification files themselves are a poor place to make prose-related changes for a few reasons:

  1. It doesn’t fix the source of the problem. Unless you’re writing your specification files by hand (see option 3a below), fixing errors in the specification file itself doesn’t actually fix the error in the content (usually a source code file) that the specification is based on.
  2. JSON and YAML files aren’t good places for writing markup. If you write your endpoint descriptions in actual Markdown files, then you have full access to your typical writing environment: spell check, syntax highlighting, linter plugins, etc.

A better solution is to lint your content prior to generating the specification file.

Option 3a: Spec-First Development

If you write your specification files by hand (i.e., they aren’t generated from external source code files), then there’s simply no reason to lint the specification file itself: you should write your prose in individual Markdown files, lint those files, and then generate your specification from the already-linted content.

I’ve put together a Gist explaining how I implemented such a workflow here.

Option 3b: Lint Your Source Code

If your specification is generated from external source code files, then you should lint those files themselves. Vale has built-in support for linting comments from many programming languages.

However, if your specification is derived from non-comment statements (such as annotations), then you’ll need to use a technique similar to Option 2a: parse the source code (which replaces the JSON/YAML file), extract the annotations, and pass them individually to Vale.

Conclusion

There are many ways to use Vale to lint OpenAPI specification files, but choosing the “best” solution likely depends on details that are specific to your own workflow needs.

If you have any questions or run into any problems, feel free to open an issue at the Vale repository.

An open-source software developer with interests in natural language processing, data science, and collaborative writing. More @ https://github.com/jdkato.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store