Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@seriousme/openapi-schema-validator

seriousme207.2kMIT2.4.1TypeScript support: included

Validate OpenApi specifications against their JSON schema

openapi, json, schema, validation

readme

OpenAPI schema validator

CI status Coverage Status NPM version npm Tested on APIs.guru

A JSON schema validator for OpenAPI specifications, it currently supports:

Tested on over 2,000 real-world APIs from AWS, Microsoft, Google etc.

Install

npm install @seriousme/openapi-schema-validator

Usage

This module is ESM only, if you need to use commonJS please see below.

// ESM
import { Validator } from "@seriousme/openapi-schema-validator";

console.log(Validator.supportedVersions.has("3.1"));
// prints true

const validator = new Validator();
const res = await validator.validate("./petstore.json");
const specification = validator.specification;
// specification now contains a Javascript object containing the specification
if (res.valid) {
  console.log("Specification matches schema for version", validator.version);
  const schema = validator.resolveRefs();
  // schema now contains a Javascript object containing the dereferenced schema
} else {
  console.log("Specification does not match Schema");
  console.log(res.errors);
}

This module can be used in CommonJS code via:

// CommonJS
const { Validator } = await (import("@seriousme/openapi-schema-validator"));

See also the upgrading guide if you come from a previous major version.

CLI for API validation

Run with global install:

npm install @seriousme/openapi-schema-validator -g
validate-api <filename>

Run without install:

npx -p @seriousme/openapi-schema-validator validate-api <filename>

Where <filename> refers to a YAML or JSON file containing the specification.

CLI for API bundling

To make it easier to combine multiple YAML or JSON files into a single specification file there is the bundle-api command. (see the validateBundle section below)

npm install @seriousme/openapi-schema-validator -g
bundle-api <specFiles> 

Run without install:

npx -p @seriousme/openapi-schema-validator bundle-api <spec files> 

The output will be a validated JSON specification. Options: -o --output <filename> the filename to save the output to, default is STDOUT. -t --type [JSON|YAML] the output format, default is JSON.

API

new Validator(ajvOptions)

The constructor returns an instance of Validator. By passing an ajv options object it is possible to influence the behavior of the AJV schema validator. AJV fails to process the openApi schemas if you set strict:true therefore this set to false if present. This is not a bug but a result of the complexity of the openApi JSON schemas.

<instance>.validate(specification)

This function tries to validata a specification against the OpenApi schemas. specification can be one of:

  • a JSON object
  • a JSON object encoded as string
  • a YAML string
  • a filename

External references are not automatically resolved so you need to inline them yourself if required e.g by using <instance>.addSpecRef() The result is an object:

{
  valid: <boolean>,
  errors: <any>  // only present if valid is false
}

<instance>.specification

If the validator managed to extract data from the specification parameter then the extracted specification is available in this property as javascript object. E.g. if you supplied a filename of a YAML file and the file was sucessfully read and its YAML decoded then the contents is here. Even if validation failed.

<instance>.version

If validation is succesfull this will return the openApi version found e.g. ("2.0","3.0","3.1). The openApi specification only specifies major/minor versions as separate schemas. So "3.0.3" results in "3.0".

<instance>.resolveRefs(options)

This function tries to resolve all internal references. External references are not automatically resolved so you need to inline them yourself if required e.g by using <instance>.addSpecRef(). By default it will use the last specification passed to <instance>.validate() but you can explicity pass a specification by passing {specification:<object>} as options. The result is an object where all references have been resolved. Resolution of references is shallow This should normally not be a problem for this use case.

<instance>.addSpecRef(subSpecification, uri)

subSpecification can be one of:

  • a JSON object
  • a JSON object encoded as string
  • a YAML string
  • a filename

uri must be a string (e.g. http://www.example.com/subspec), but is not required if the subSpecification holds a $id attribute at top level. If you specify a value for uri it will overwrite the definition in the $id attribute at top level.

Sometimes a specification is composed of multiple files that each contain parts of the specification. The specification refers to these sub specifications using external references. Since references are based on URI's (so Identifier and not Location as in URL's!) there needs to be a way to tell the validator how to resolve those references. This is where this function comes in:

E.g.: we have a main specification in main-spec.yaml containing:

...
paths:
  /pet:
    post:
      tags:
        - pet
      summary: Add a new pet to the store
      description: ''
      operationId: addPet
      responses:
        '405':
          description: Invalid input
      requestBody:
        $ref: 'http://www.example.com/subspec#/components/requestBodies/Pet'

And the reference is in sub-spec.yaml, containing:

components:
  requestBodies:
    Pet:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'
        application/xml:
          schema:
            $ref: '#/components/schemas/Pet'
      description: Pet object that needs to be added to the store
      required: true
  ...

Then the validation can be performed as follows:

import { Validator } from "@seriousme/openapi-schema-validator";
const validator = new Validator();
await validator.addSpecRef("./sub-spec.yaml", "http://www.example.com/subspec");
const res = await validator.validate("./main-spec.yaml");
// res now contains the results of the validation across main-spec and sub-spec
const specification = validator.specification;
// specification now contains a Javascript object containing the specification
// with the subspec inlined

<instance>.validateBundle([specification,subspecification, ...])

This offers an alternative to the combination of addSpecRef and validate. You can pass an array of (sub)specifications where each can be one of:

  • a JSON object
  • a JSON object encoded as string
  • a YAML string
  • a filename

There can only be one main specification present (starting with swagger/openapi) but it does not have to be the first one. If you provide filenames and the files do not have $id attributes, then the $id attribute will be generated from the filename.

If we take the YAML specifications from the previous example then validation can be performed as follows:

import { Validator } from "@seriousme/openapi-schema-validator";
const validator = new Validator();
const res = await validator.validateBundle([ "./sub-spec.yaml", "./main-spec.yaml"]);
// res now contains the results of the validation across main-spec and sub-spec
const specification = validator.specification;
// specification now contains a Javascript object containing the specification
// with the subspec inlined

Validator.supportedVersions

This static property returns the OpenApi versions supported by this package as a Set. If present, the result of <instance>.version is a member of this Set.

Notes

The JSONschemas are copied from the OpenAPI specification JSONschemas which might differ from the OpenAPI specification HTML pages! If you find a bug in a schema (e.g. because it behaves differently than specified in the HTML) then please raise an issue at https://github.com/OAI/OpenAPI-Specification. Shortly after the specification writers update their schema the automation will pick it up and include the updated version in this module.

License

Licensed under the MIT license

changelog

Changelog

[Unreleased]

Changed

[v2.4.1] 27-04-2025

Changed

  • chore: replace minimist by node:util.parseArgs

[v2.4.0] 21-03-2025

Changed

  • feature: updated OpenApi schema 3.1 to version 2025-02-13

[v2.3.1] 19-01-2025

Changed

  • updated dependencies
    • c8 ^10.1.2 → ^10.1.3

[v2.3.0] 22-11-2024

Changed

  • updated OpenApi 3.1 schema to version 2024-11-14

[v2.2.5] 13-11-2024

Changed

  • fix: reverted: removed dependency on "node:url" to aid in bundling because of Windows incompatibility

[v2.2.4] 12-11-2024

Changed

  • fix: removed dependency on "node:url" to aid in bundling
  • updated dependencies
    • @biomejs/biome ^1.8.3 → ^1.9.4

[v2.2.3] 31-08-2024

Changed

  • fix: fixed biome formatting of package.json

[v2.2.2] 31-08-2024

Changed

  • updated dependencies
    • @biomejs/biome ^1.5.3 → ^1.8.3
    • ajv ^8.12.0 → ^8.17.1
    • c8 ^10.1.1 → ^10.1.2

[v2.2.1] 17-02-2024

Changed

  • fix: added validateBundle() to index.d.ts

[v2.2.0] 17-02-2024

Changed

  • feature: added validationBundle functionality including bundle-api cli
  • updated dependencies
    • @biomejs/biome ^1.5.2 → ^1.5.3

[v2.1.6] 20-01-2024

Changed

  • Updated dependencies
    • @biomejs/biome ^1.3.3 → ^1.5.2
    • c8 ^9.0.0 → ^9.1.0

[v2.1.5] 16-11-2023

Changed

  • fix: validation after resolveRefs (tansin)

[v2.1.4] 13-11-2023

Changed

  • fix: recursive refs work during validation as well
  • fix: update index.d.ts to include single string errors on validate

[v2.1.3] 12-11-2023

Changed

  • fix: ref's are now checked during validation as well
  • Updated dependencies
    • @biomejs/biome ^1.2.2 → ^1.3.3

[v2.1.2] 27-09-2023

Changed

  • fix: added addSpecRef() to index.d.ts
  • Updated dependencies
    • @biomejs/biome ^1.1.2 → ^1.2.2

[v2.1.1] 13-09-2023

Changed

  • chore: added Biome for formatting and linting
  • chore: removed tap
  • chore: removed node-fetch
  • Updated dependencies
    • ajv ^8.11.0 → ^8.12.0
    • c8 ^7.12.0 → ^8.0.1

[v2.1.0] 14-10-2022

Changed

  • Update OAS v3.1 to the updated 2022-10-07 schema

[v2.0.3] 28-09-2022

Changed

  • Fix ref handing in resolveRefs
  • Updated dependencies
    • c8 ^7.11.2 → ^7.12.0
    • node-fetch ^3.2.3 → ^3.2.10
    • tap ^16.0.1 → ^16.3.0

[v2.0.2] 12-05-2022

Changed

  • Fix file handling on Windows

[v2.0.1] 26-04-2022

Changed

  • Fix CLI issue and doc issue (@tbcarver)

[v2.0.0] 25-04-2022

Changed

  • Removed Node 10/12 support from code
  • Migrated to ESM, see UPGRADING.md for details

[v1.7.1] 22-04-2022

Changed

  • Updated dependencies
    • ajv ^8.6.3 → ^8.11.0
    • node-fetch ^3.0.0 → ^3.2.3
    • tap ^16.0.0 → ^16.0.1

[v1.7.0] 11-03-2022

Changed

  • Updated OAS v3.0 to the updated 2021-09-28 schema (only descriptions changed)
  • Updated OAS v3.1 to 2022-02-27 schema

[v1.6.1] 22-2-2022

Changed

  • Fixed error in addSpecRef example in the README

[v1.6.0] 09-10-2021

Changed

  • New feature, now supports external refs, see addSpecRef in the README.

[v1.5.1] 08-10-2021

Changed

  • Fixed error message on URI ref without a path

[v1.5.0] 08-10-2021

Changed

  • Updated OAS v3.0 to 2021-09-28 schema
  • Updated OAS v3.1 to 2021-09-28 schema

[v1.4.0] 25-09-2021

Changed

[v1.3.0] 07-07-2021

Changed

  • Added validation of formats
  • Updated dependencies
    • ajv ^8.6.0 → ^8.6.1

[v1.2.0] 27-06-2021

Changed

  • Cache AJV validators so that multiple validation calls are faster
  • Added CLI tool

[v1.1.6] 26-06-2021

Changed

  • Switched to original draft-04 schemas instead of converted draft-07 schemas now that AJV supports draft-04

[v1.1.5] 25-06-2021

Changed

  • fixed YAML parsing of date strings (e.g: version: 2021-06-25)
  • Updated dependencies
    • ajv ^8.3.0 → ^8.6.0

[v1.1.4] 18-06-2021

Changed

  • force AJV options strict:false and validateFormats:false even if user supplies empty ajvOptions

[v1.1.3] 28-05-2021

Changed

  • Support schema 3.1 2021-05-20

[v1.1.2] 14-05-2021

Changed

  • Added Node 10 support

[v1.1.1] 14-05-2021

Changed

  • Added CommonJS example to README.md

[v1.1.0] 14-05-2021

Changed

  • Converted from ESM to CommonJS to improve compatibility

[v1.0.3] 10-05-2021

Changed

  • Fixed bug in v2.0 schema that disallowed multiple parameters

[v1.0.2] 10-05-2021

Changed

  • Updated example in README.md

[v1.0.1] 09-05-2021

Changed

  • Updated dependencies
  • Reworked README
  • Applied LGTM suggestions

[v1.0.0] 09-05-2021

Initial version