A Swagger 2.0 and OpenAPI 3.x validation and parsing engine
@readme/openapi-parser
is a library to validate and parse OpenAPI and Swagger API definitions. It is a hard fork of @apidevtools/swagger-parser and offers support for improved validation error messages as well as error leveling.
npm install @readme/openapi-parser
- Parses API definitions in either JSON or YAML formats.
- Validates against the Swagger 2.0, OpenAPI 3.0, or OpenAPI 3.1 specifications.
- Resolves all
$ref
pointers, including external files and URLs. - Can bundle all of your referenced API definitions into a single file that only has internal
$ref
pointers. - Can dereference all
$ref
pointers, giving you a normal JSON object that's easy to work with. - Works in all modern browsers!
import { validate } from '@readme/openapi-parser';
try {
const api = await validate(petstore);
console.log('API name: %s, Version: %s', api.info.title, api.info.version);
} catch (err) {
console.error(err);
}
Validates the API definition against the Swagger 2.0, OpenAPI 3.0, or OpenAPI 3.1 specifications.
In addition to validating the API definition against their respective specification schemas, it will also be validated against specific areas that aren't covered by the Swagger or OpenAPI schemas, such as duplicate parameters, invalid component schema names, or duplicate operationId
values.
If validation fails an error will be thrown with information about what, and where, the error lies within the API definition.
Internally this method invokes dereference()
so the returned object, whether it's a Swagger or OpenAPI definition, will be fully dereferenced.
import { validate } from '@readme/openapi-parser';
const result = await validate(petstore);
if (result.valid) {
console.log('🍭 The API is valid!');
} else {
console.error(result.errors);
}
Error output example
[
{
message: 'REQUIRED must have required property 'url'
7 | },
8 | "servers": [
> 9 | {
| ^ url is missing here!
10 | "urll": "http://petstore.swagger.io/v2"
11 | }
12 | ],'
}
]
By default, validate
returns a ValidationResult
which will contain an array of errors. If you would like to convert this shape into a human-readable error string, you can do so by utilizing our compileErrors
utility:
import { validate, compileErrors } from '@readme/openapi-parser';
const result = await validate(petstore);
if (result.valid) {
console.log('🍭 The API is valid!');
} else {
console.error(compileErrors(result));
}
OpenAPI schema validation failed.
REQUIRED must have required property 'url'
7 | },
8 | "servers": [
> 9 | {
| ^ url is missing here!
10 | "urll": "http://petstore.swagger.io/v2"
11 | }
12 | ], */
compileErrors
can also be used to turn validation warnings into a human-readable string.
This library supports downgrading certain specification-level checks, that would be normally classified as a validation error, to a general warning. To configure these you do so by supplying the validate()
call your config:
import { validate, compileErrors } from '@readme/openapi-parser';
const result = await validate(petstore, {
validate: {
rules: {
openapi: {
'path-parameters-not-in-path': 'warning',
},
},
},
});
if (result.valid) {
if (result.warnings.length) {
console.warn('🚸 The API is valid but has some warnings.');
console.warn(result.warnings);
} else {
console.log('🍭 The API is valid!');
}
} else {
console.error(compileErrors(result));
}
The following OpenAPI rules can be downgraded to warnings. By default, they are all treated as errors. We do not support downgrading any Swagger specification errors to warnings -- only OpenAPI.
Rule | What it validates |
---|---|
array-without-items |
Schemas that are defined as type: array must also have an items schema. |
duplicate-non-request-body-parameters |
Parameters must be unique. |
duplicate-operation-id |
The operationId definition in a path object must be unique. |
non-optional-path-parameters |
Parameters that are defined within the path URI must be specified as being required . |
path-parameters-not-in-parameters |
Path parameters defined in a path URI path template must also be specified as part of that paths parameters . |
path-parameters-not-in-path |
Path parameters defined in parameters must also be specified in the path URI with path templating. |
This library supports colorizing errors with the picocolors library. To enable it, supply the validation.errors.colorize
option. The default behavior is false
.
const result = await validate(petstore, {
validate: {
errors: {
colorize: true,
},
},
});
Dereferences all $ref
pointers in the supplied API definition, replacing each reference with its resolved value. This results in an API definition that does not contain any $ref
pointers. Instead, it's a normal JSON object tree that can easily be crawled and used just like any other object. This is great for programmatic usage, especially when using tools that don't understand JSON references.
import { dereference } from '@readme/openapi-parser';
const api = await dereference(petstore);
// The `api` object is a normal JSON object so you can access any part of the
// API definition using object notation.
console.log(api.components.schemas.pet.properties.name); // => { type: "string" }
Bundles all referenced files and URLs into a single API definition that only has internal $ref
pointers. This lets you split up your definition however you want while you're building it, but later combine all those files together when it's time to package or distribute the API definition to other people. The resulting definition size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.
import { bundle } from '@readme/openapi-parser';
const api = await bundle(myAPI);
console.log(api.components.schemas.pet); // => { $ref: "#/components/schemas~1pet.yaml" }
Parses the given API definition, in JSON or YAML format, and returns it as a JSON object. This method does not resolve $ref
pointers or dereference anything. It simply parses one file and returns it.
import { parse } from '@readme/openapi-parser';
const api = await parse(myAPI);
console.log('API name: %s, Version: %s', api.info.title, api.info.version);