OpenAPI V3 Spec validation tools

Project structure

  • oas-validator-core: core apis and skeletons implementations
  • oas-validator-core-spring: Spring Boot Starter for core skeletons
  • oas-validator-test: test helpers for core api
  • oas-validator-compliance: check style validators
  • oas-validator-compliance-spring: Spring Boot Starter for check style validators
  • oas-validator-compatibility: compatibility validators
  • oas-validator-compatibility-spring: Spring Boot Starter for compatibility validators
  • oas-validator-web: web ui

Style check rules

OAS must compatible with OAS 3.0.2, besides must obey the following rules.

String patterns

  • Lower Camel Case: initial letter lowercase camel case, regex is ^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$
  • Upper Camel Case: initial letter uppercase camel case, regex is ^[A-Z]([a-z0-9]+[A-Z]?)*$
  • Upper Hyphen Case: initial letter uppercase, multiple words concat with -, such as Content-Type, Accept, X-Rate-Limit-Limit, regex is ^([A-Z][a-z0-9]*-)*([A-Z][a-z0-9]*)$

OpenAPI Object doc

Info Object doc

  • description property, required

Tag Object doc

Paths Object doc

Path Item Object doc

Operation Object doc

Parameter Object doc

Request Body Object doc

Media Type Object doc

Responses Object doc

Response Object doc

Schema Object doc

Encoding Object doc

Header Object doc

Components Object doc

Compatibility check rules

Check whether new OAS spec compatibile with old spec.

Notice: OAS could use Reference Object, two OAS which are different in text maybe semantically same. For example, below old OAS doesn’t use Reference Object while the new one uses:

Old OAS

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    post:
      summary: List all pets
      operationId: listPets
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  Foo:
                    type: string
      responses:
        '200':
          description: A paged array of pets

New OAS

paths:
  /pets:
    post:
      operationId: listPets
      requestBody:
        content:
          application/json: 
            schema:
              $ref: '#/components/schemas/Foo'
      responses:
        '200':
          description: A paged array of pets
components:
  schemas:
    Foo:
      type: array
      items:
        type: object
        properties:
          Foo:
            type: string

So, when do compatibility check we resolve Reference Object in old and new OAS first, then do the check, below is the code snippet using swagger-parser:

OpenAPIV3Parser parser = new OpenAPIV3Parser();

ParseOptions parseOptions = new ParseOptions();
parseOptions.setResolve(true);
parseOptions.setResolveCombinators(true);
parseOptions.setResolveFully(true);
parseOptions.setFlatten(false);

SwaggerParseResult parseResult = parser.readContents(content, null, parseOptions);

So if compatibility violations be found, the reported location will be different from the location in origin OAS spec.

Paths Object doc

Path Item Object doc

Operation Object doc

Parameter Object doc

  • required property, only allow true(old) -> false(new) change
  • allowEmptyValue property, only allow false(old) -> true(new) change
  • style property, new and old must be identical
  • explode property, new and old must be identical
  • allowReserved property, only allow false(old) -> true(new) change
  • schema property, see Schema Object compatibility check rules
  • contentproperty, new OAS must include all old OAS media type (content keys), and add new media type is not allowed

Request Body Object doc

Media Type Object doc

Responses Object doc

  • default property, if old OAS doesn’t define default, then new OAS should not define default too.
  • {Http Status Code} property, new OAS is not allowed to add one.
  • See Response Object compatibility check rules

Response Object doc

Schema Object doc

OAS allows Schema Object be directly or indirectly in:

In different context compatibility check rules are different.

In request context

When Schema Object is in response context, only allow change from more specific form to less specific form.

  • type, format combination allowed change:
Old (type,format) New (type,format)
integer, null integer, int64
number, double
number, null
integer, int32 integer, int64
integer, null
number, float
number, double
number, null
integer, int64 integer, null
number, double
number, null
number, null number, double
number, float number, null
number, double
number, double number, null
string, null string, password
string, password string, null
  • allOf, oneOf, anyOf property, combine them first then do check
  • multipleOf property, if old OAS is null, then new OAS must == old OAS or new OAS is a factor of old OAS, eg, 6(old)->3(new)
  • maximum, maxLength, maxItems, maxProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must be >= old OAS
  • minimum, minLenght, minItems, minProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must be <= old OAS.
  • exclusiveMaximum, exclusiveMinimum property, only allow change true(old)->false(new)
  • uniqueItems property, only allow change true(old)->false(new)
  • required property, new OAS must == old OAS or new OAS is old OAS subset
  • enum property, new OAS must == old OAS or new OAS is old OAS superset
  • properties property, new OAS could add or delete property name(properties key)
  • nullable property, only allow change false(old)->true(new)
  • discriminator property, new and old must be identical
  • xml property, new and old must be identical
  • readOnly, writeOnly property, new and old must be identical

In response context

When Schema Object is in response context, only allow change from less specific form to more specific form.

  • type, format combination allowed change:
Old (type,format) New (type,format)
integer, null integer, int64
integer, int32
integer, int64 integer, null
interger, int32
number, null number, double
number, float
number, double number, null
number, float
string, null string, password
string, password string, null
  • allOf, oneOf, anyOf property, combine them first then do check
  • multipleOf property if old OAS is null. new OAS must == old OAS or new OAS must be a multiple of old OAS, eg, 3(old)->6(new)
  • maximum, maxLength, maxItems, maxProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must <= old OAS
  • minimum, minLenght, minItems, minProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must >= old OAS
  • exclusiveMaximum, exclusiveMinimum property, only allow change false(old)->true(new)
  • uniqueItems property, only allow change false(old)->true(new)
  • required new OAS must == old OAS or new OAS is old OAS superset
  • enum property, new OAS must == old OAS or new OAS is old OAS subset
  • properties property, new OAS could add or delete property name(properties key)
  • nullable property , only allow change true(old)->false(new)
  • discriminator property, new and old must be identical
  • xml property, new and old must be identical
  • readOnly, writeOnly property, new and old must be identical

Encoding Object doc

Notice: Encoding Object only apply to Request Body Object

  • contentType property, new and old must be identical
  • headers property, new OAS can not add new he header name (headers key), but and delete header name
  • style property, new and old must be identical
  • explode property, new and old must be identical
  • allowReserved property, only allow change false(old) -> true(new)

Header Object doc

Components Object doc

Components Object defines reusable OAS Object, but when doing compatibility check all $ref are resolved, so no need to check Components Object compatibility.