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:
As you can see above, the only parts we’re really interested in are the
description (which can contain Markdown), and
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
petstore.yaml file from Swagger.
Option 1: No Processing
The easiest way to lint an OpenAPI specification file is to simply pass it, as is, to Vale:
$ vale petstore.yaml
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
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):
You can use this script by passing your spec as a parameter:
$ python swagger.py petstore.yaml
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:
$ java -jar swagger2markup-cli-1.3.3.jar convert -i petstore.yaml -f swagger && vale swagger.adoc
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
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:
- 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.
- 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.
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.
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.