Giter Club home page Giter Club logo

openapi-schema-validator's Introduction

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 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.

License

Licensed under the MIT license

openapi-schema-validator's People

Contributors

dependabot[bot] avatar seriousme avatar tansin avatar tbcarver avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

openapi-schema-validator's Issues

Add local file reference to README

If i have a file file structure like:

api.v0.yaml
v0/auth.v0.yaml

I want to validate api.v0.yaml that references v0/auth.v0.yaml.

  /v0/auth/register:
    post:
      $ref: v0/auth.v0.yaml#/paths/~1v0~1auth~1register/post
      tags:
        - Auth
      summary: Register a new account

I get must NOT have unevaluated properties, which I understand is expected behaviour from the README, I can't figure out how to use <instance>.addSpecRef(subSpecification, uri) to get this working.

Thanks

$ref to other files

Hello !

First thank you for this project and fastify-openapi-glue, it really helps for implementing a documentation-first API ๐Ÿ™‚

I'm currently trying to use fastify-openapi-glue with an OpenAPI definition splitted in multiple files. From what I saw, it raises an error in this package.

If I understand correctly, this package doesn't retrieve the other files and thus I should provide a self-contained definition file ?
Or did I miss something ? ๐Ÿ™‚

Just to give all the infos, I'm using the syntax for getting other files like that:

# OpenAPI file
# [...]
paths:
  /todos:
    $ref: "./list_todos.yaml"

And it fails in https://github.com/seriousme/openapi-schema-validator/blob/master/resolve.js#L33 as there is no # character in the uri, which gives the error Cannot read property 'length' of undefined.

Thanks in advance for the input

The method addSpecRef is missing in index.d.ts

Hello and thanks for this useful piece of software!

I'm using the version 2.1.1 in a typescript project. The method addSpecRef is missing in index.d.ts though, so that the typescript compiler complains.

Cannot perform validation in strict mode

Using version 1.1.3, I was trying to validate schema using strict mode. It seems so that feature not supported, or in some was is not compatible.

As soon as strict mode enabled fails with error:

Error: unknown format "uri" ignored in schema at path "#/properties/url"
I think error refers not schema I validate but rather different schema
https://json-schema.org/draft/2020-12/schema
or
https://spec.openapis.org/oas/3.1/schema/2021-05-20
not sure.

Typos in ref ids are not detected

Hello, it looks like your library makes a good job in finding the format issues. However, incorrect ref ids are not detected. I'm not sure if it's intended or not.

Version used: 2.1.2

Schema example:

openapi: 3.0.0
info:
  title: test
  version: 1.0.0
paths:
  /get:
    get:
      summary: test
      description: test
      parameters:
        - name: param
          in: query
          description: param
          required: true
          schema:
            type: string
          example: "foo"
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/nonExisting1"
components:
  schemas:
    testObject:
      type: object
      properties:
        prop1:
          type: string
    searchResults:
      type: object
      properties:
        testObjects:
          type: array
          items:
            $ref: "#/components/schemas/nonExisting2"

Actual result:
"valid": true
I was using the CLI command for testing: npx -p @seriousme/openapi-schema-validator validate-api "invalid.spec.yaml"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.