Detects stylistic and structural issues in OpenAPI schemas, improving their quality.
apigenie lint [OPTIONS] FILES
The OpenAPI linter helps developers and teams create high-quality, consistent, and well-structured schemas. It achieves this by validating schemas against a set of configurable lint rules.
Each rule in the linter focuses on a specific aspect of an OpenAPI schema. Here are some examples:
operation-description-defined
: Ensures that all operations have
meaningful descriptions.operation-success-response
: Ensures that all operations define a success
response (e.g. 201 Created
).paths-max-count
and paths-max-depth
: Limit API complexity
by checking the number of path items and depth (e.g. a number of segments)
or URLs.Each rule can have a severity level assigned, indicating its importance.
Possible values for severity are warning
and error
. Both warnings and
errors show up in the linter output, but only errors prevent the linter check
from succeeding.
Some rules may accept options that adjust how they evaluate the schema.
The API Genie linter currently offers 53 built-in rules, with over 20 additional rules under active development.
To simplify configuration and provide more flexibility, rules can be combined into rulesets. A ruleset is a named group of rules with assigned severity levels and options.
There might be situations where you want to temporarily disable a rule for a
specific part of a schema. This might be due to a legacy issue, ongoing
development, or a specific API decision. To do this, annotate parts of your
OpenAPI schema with the x-apigenie-lint-disable
extension. The value of this
extension must be a list of rule names you want to disable.
Rules can be disabled on any schema object, including OpenAPI
object itself.
Disabling a rule on specific schema object applies to that object and its
descendants within the schema hierarchy.
For example, in the snippet below, the
contact-defined rule is disabled on
the Info
schema object. However, it will also be enforced on the nested
Contact
object because Contact
is a descendant of Info
within the schema
structure.
info:
x-apigenie-lint-disable:
- contact-defined
A couple of final remarks:
Some issues found by the apigenie lint
command can be automatically fixed.
To do this, run the command with the --fix
option.
Apart from rules, API Genie linter allows to customize the way it displays results. It ships with several built-in formatters, described below, in subsections.
Formatters differ in the way they present data, but all of them sort issues by:
Note: If you used ESLint you may notice that the list of formatters API Genie provides is close to that of ESLint. This is by no coincidence, as both tools aim to be usable in many different environments.
Outputs results in the Checkstyle format.
<?xml version="1.0" encoding="utf-8"?>
<checkstyle version="4.3">
<file name="/apigenie/data/openapi.yaml">
<error line="2" column="2" severity="error" message="Info summary is missing or empty" source="info-defined"/>
<error line="12" column="4" severity="warning" message="Tag 'Articles' has no meaningful description defined" source="tag-description-defined"/>
<error line="13" column="4" severity="warning" message="Tag 'Comments' has no meaningful description defined" source="tag-description-defined"/>
<error line="14" column="4" severity="warning" message="Tag 'Favorites' has no meaningful description defined" source="tag-description-defined"/>
<error line="15" column="4" severity="warning" message="Tag 'Profile' has no meaningful description defined" source="tag-description-defined"/>
</file>
</checkstyle>
Mimicks the default output of JSHint.
/apigenie/data/openapi.yaml: line 2, col 2, Error - Info summary is missing or empty. (info-defined)
/apigenie/data/openapi.yaml: line 12, col 4, Warning - Tag 'Articles' has no meaningful description defined. (tag-description-defined)
/apigenie/data/openapi.yaml: line 13, col 4, Warning - Tag 'Comments' has no meaningful description defined. (tag-description-defined)
/apigenie/data/openapi.yaml: line 14, col 4, Warning - Tag 'Favorites' has no meaningful description defined. (tag-description-defined)
/apigenie/data/openapi.yaml: line 15, col 4, Warning - Tag 'Profile' has no meaningful description defined. (tag-description-defined)
Prints results as a single HTML file. Issues are displayed in a table, every issue takes one table row.
<!DOCTYPE html>
<html>
<body>
<section id="overview">
<h1>API Genie Report</h1>
<ul>
<li>Total: 224</li>
<li>Errors: 32</li>
<li>Warnings: 192</li>
</ul>
</section>
<section id="issues">
<table>
<caption>/apigenie/data/openapi.yaml</caption>
<tr>
<td class="pos">2:2</td>
<td class="error">Error</td>
<td>Info summary is missing or empty</td>
<td>
<a href="https://apigenie.pl/techdocs/linter/rules/info-defined">info-defined</a>
</td>
</tr>
<tr>
<td class="pos">12:4</td>
<td class="warning">Warning</td>
<td>Tag 'Articles' has no meaningful description defined</td>
<td>
<a href="https://apigenie.pl/techdocs/linter/rules/tag-description-defined">tag-description-defined</a>
</td>
</tr>
</table>
</body>
</html>
Outputs lint results in JSON file. This format is useful if you want to process linter result programmatically.
[
{
"filePath": "/apigenie/data/openapi.yaml",
"messages": [
{
"column": 2,
"line": 2,
"message": "Info summary is missing or empty",
"ruleId": "info-defined",
"severity": "error"
},
{
"column": 4,
"line": 12,
"message": "Tag 'Articles' has no meaningful description defined",
"ruleId": "tag-description-defined",
"severity": "warning"
},
... more issues ...
]
}
]
Outputs results to format compatible with the JUnit Jenkins plugin.
<?xml version="1.0" encoding="utf-8"?>
<testsuites>
<testsuite package="apigenie" time="0" tests="224" errors="224" name="/apigenie/data/openapi.yaml">
<testcase time="0" name="apigenie.info-defined" classname="apigenie.info-defined">
<failure message="Info summary is missing or empty"><![CDATA[line 2, col 2, Error - Info summary is missing or empty. (info-defined)]]></failure>
</testcase>
<testcase time="0" name="apigenie.tag-description-defined" classname="apigenie.tag-description-defined">
<failure message="Tag 'Articles' has no meaningful description defined"><![CDATA[line 12, col 4, Warning - Tag 'Articles' has no meaningful description defined. (tag-description-defined)]]></failure>
</testcase>
<testcase time="0" name="apigenie.tag-description-defined" classname="apigenie.tag-description-defined">
<failure message="Tag 'Comments' has no meaningful description defined"><![CDATA[line 13, col 4, Warning - Tag 'Comments' has no meaningful description defined. (tag-description-defined)]]></failure>
</testcase>
</testsuite>
</testsuites>
This is the default formatter. It presents result as table, with values being highligted in different colors.
764:6 warning Unused shared component unused-shared-component
769:12 warning Object schema does not define constraints restricting its size schema-constraints
769:12 error Object schema does not disable additional properties schema-no-additional-properties
777:6 warning Unused shared component unused-shared-component
781:8 error Schema with integer type does not define proper format schema-format-defined
781:8 warning Integer schema does not define constraints restricting its range schema-constraints
785:6 warning Unused shared component unused-shared-component
789:8 error Schema with integer type does not define proper format schema-format-defined
789:8 warning Integer schema does not define constraints restricting its range schema-constraints
795:6 warning Unused shared component unused-shared-component
224 issues (32 errors, 192 warnings)
0 errors, 6 warnings are potentially auto-fixable
Outputs results to the Test Anything Protocol (TAP) specification format.
TAP version 14
1..1
not ok - /apigenie/data/openapi.yaml
---
errorCount: 32
issues:
- column: 2
line: 2
message: Info summary is missing or empty
ruleId: info-defined
severity: error
- column: 4
line: 12
message: Tag 'Articles' has no meaningful description defined
ruleId: tag-description-defined
severity: warning
- column: 4
line: 13
message: Tag 'Comments' has no meaningful description defined
ruleId: tag-description-defined
severity: warning
Outputs results to a format similar to many commands in UNIX-like systems.
If you use grep
or awk
, this format may be best for you.
/apigenie/data/openapi.yaml:2:2: Info summary is missing or empty. [Error/info-defined]
/apigenie/data/openapi.yaml:12:4: Tag 'Articles' has no meaningful description defined. [Warning/tag-description-defined]
/apigenie/data/openapi.yaml:13:4: Tag 'Comments' has no meaningful description defined. [Warning/tag-description-defined]
/apigenie/data/openapi.yaml:14:4: Tag 'Favorites' has no meaningful description defined. [Warning/tag-description-defined]
/apigenie/data/openapi.yaml:15:4: Tag 'Profile' has no meaningful description defined. [Warning/tag-description-defined]
/apigenie/data/openapi.yaml:16:4: Tag 'Tags' has no meaningful description defined. [Warning/tag-description-defined]
Outputs results to format compatible with the integrated terminal of the Visual Studio IDE.
/apigenie/data/openapi.yaml(2,2): error info-defined : Info summary is missing or empty.
/apigenie/data/openapi.yaml(12,4): warning tag-description-defined : Tag 'Articles' has no meaningful description defined.
/apigenie/data/openapi.yaml(13,4): warning tag-description-defined : Tag 'Comments' has no meaningful description defined.
/apigenie/data/openapi.yaml(14,4): warning tag-description-defined : Tag 'Favorites' has no meaningful description defined.
/apigenie/data/openapi.yaml(15,4): warning tag-description-defined : Tag 'Profile' has no meaningful description defined.
/apigenie/data/openapi.yaml(16,4): warning tag-description-defined : Tag 'Tags' has no meaningful description defined.
Optional path to the configuration file. If not specified, the default configuration is used. For details, see the configuration section.
If possible, automatically fixes problems it finds. Modified file is written under the same name as the original.
Sets the formatter to display the linter result. Supported formatter names are:
checkstyle
compact
html
json
junit
stylish
- the default formattertap
unix
visualstudio
The linter stores its configuration under the #/commands/linter
key in the
configuration file. See the global configuration
section to understand how this file is structured.
The linter configuration allows to apply rulesets, enable or disable certain rules, modify rule severity levels, or modify rules’ options.
Example: a minimal confiration illustrating all possible variants of configuring rules.
version: 1.0
commands:
lint:
extends:
- recommended
# ... more rulesets to extend from ...
rules:
info-defined: off
paths-max-count:
- error
- 30
schema-datetime-suffix:
- error
- At
tags-unique: error
# ... more rules ...
If the configuration file is not specified, linter uses the default configuration:
version: 1.0
commands:
lint:
extends:
- recommended
This block lists rulesets whose configuration will be used and combined to create the final set of rules, rule severity levels and options.
The value of this block, if present, must be an array of supported ruleset names. Linter will read all rulesets’ configurations, in the order they are listed. If two rulesets contain the same rule, linter uses the configuration from the ruleset that was specified later in the list.
These are overrides to the rules’ configurations from rulesets.
If present, value of this block must be a map. Keys of the map must be valid rule names, and values can be either strings or two-element arrays.
For valid rule names see the rule index page.
Such blocks configure a rule named RULE_ID
. Each block may be a string or a
two-element array.
off
- to disable rulewarning
- to set rule severity to warningerror
- to set rule severity to errorwarning
or
error
).See the documentation of each rule to find what options it accepts.
Examples
info-defined
rule:version: 1.0
commands:
lint:
rules:
info-defined: off
paths-max-count
rule to issue
an error when the number of path items is larger than 30. If the number is
below or equal to 30, the rule does not produce an error or warning.version: 1.0
commands:
lint:
rules:
paths-max-count:
- error
- 30