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 asContent-Type,Accept,X-Rate-Limit-Limit, regex is^([A-Z][a-z0-9]*-)*([A-Z][a-z0-9]*)$
OpenAPI Object doc
openapiproperty must be 3.0.x and >= 3.0.2infopropety, see Info Object style check rulespathsproperty, must provide, see Paths Object style check rulescomponentsproperty, see Components Object style check rulestagsproperty should at least provide one Tag Objectsecurityproperty, should not provide
Info Object doc
descriptionproperty, required
Tag Object doc
nameproperty, must be Upper Camel Casedescriptionproperty, required- Every tag should be referenced by at least one Operation Object
Paths Object doc
- path must be Lower Camel Case, including Path Templating variable
Path Item Object doc
get/post/put/delete/...properties, see Operation Object style check rulesparametersproperty, see Parameter Object style check rules
Operation Object doc
summaryproperty, requiredoperationIdproperty, must be Lower Camel Caseparametersproperty, see Parameter Object style check rulesrequestBodyproperty, see Request Body Object style check rulesresponsesproperty, see Responses Object style check rulestagsproperty, can only provide one tag, must be in the range of OpenAPI Objecttagspropertyserversproperty, should not provide
Parameter Object doc
descriptionproperty, requirednameproperty- if
inis path, query or cookie, then must be Lower Camel Case - if
inis header, then must be Upper Hyphen Case
- if
schemaproperty, see Schema Object check sytle rulescontentproperty, see Media Type Object style check rules
Request Body Object doc
descriptionproperty, requiredcontentproperty, see Media Type Object style check rules
Media Type Object doc
schemaproperty, required. See Schema Object style check rulesencodingproperty, see Encoding Object style check rules
Responses Object doc
Response Object doc
descriptionproperty, requiredheadersproperty, name (headerskey) must be Upper Hyphen Casecontentproperty, see Media Type Object style check rules
Schema Object doc
titleproperty, required if parent is Schema Object or Components Objectpropertiesproperty, name(propertieskey) must be Lower Camel Case- Sub Schema, see Schema Object style check rules
Encoding Object doc
headersproperty, name(headerskey) must be Upper Hyphen Case
Header Object doc
descriptionproperty, requiredschemaproperty, see Schema Object style check rulescontentproperty, see Media Type Object style check rules
Components Object doc
schemasproperty, name must be Upper Camel Caseresponsesproperty, name must be Upper Camel Caseparametersproperty, name must be Upper Camel Caseexamplesproperty, name must be Upper Camel CaserequestBodiesproperty, name must be Upper Camel Caseheadersproperty, name must be Upper Hyphen Caselinksproperty, name must be Upper Camel Casecallbacksproperty, name must be Upper Camel Case
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
- New OAS must include all the
pathappears in 旧OAS. Ifpathuses Path Templating, even the variable name changed, will be considered semantically different. For example/pets/{foo}and/pets/{bar}are different.
Path Item Object doc
- New OAS must inclued all old OAS get/put/post/delete/…Operation Object
Operation Object doc
operationIdproperty, new and old must be identicalparametersproperty, check work must also consider Path Item Object parameters property:- New OAS could add new Parameter Object, but the new Parameter Object
requiredproperty must befalse - New OAS could deleteParameter Object
- The check on Parameter Object see Parameter Object compatibility check rules(Under the same Operation Object Parameter Object is identified by
nameandinproperty)。
- New OAS could add new Parameter Object, but the new Parameter Object
requestBodyproperty, see Request Body Object compatibility check rulesresponsesproperty, seeResponses Object compatibility check rules
Parameter Object doc
requiredproperty, only allowtrue(old) -> false(new)changeallowEmptyValueproperty, only allowfalse(old) -> true(new)changestyleproperty, new and old must be identicalexplodeproperty, new and old must be identicalallowReservedproperty, only allowfalse(old) -> true(new)changeschemaproperty, see Schema Object compatibility check rulescontentproperty, new OAS must include all old OAS media type (contentkeys), and add new media type is not allowed
Request Body Object doc
contentproperty, new OAS must include all old OAS media type (contentkeys)requiredproperty, only allowtrue(old) -> false(new)change
Media Type Object doc
schemaproperty, see Schema Object compatibility check rulesencodingproperty, this property only apply torequestBody, so new OAS and old OAS property name(encodingkey) must be identical
Responses Object doc
defaultproperty, if old OAS doesn’t definedefault, then new OAS should not definedefaulttoo.{Http Status Code}property, new OAS is not allowed to add one.- See Response Object compatibility check rules
Response Object doc
headersproperty, new OAS must include all old OAS header name(headerskeys), and add new header name is allowedcontentproperty, new OAS must include all old OAS media type(contentkeys), and add new media type is allowed
Schema Object doc
OAS allows Schema Object be directly or indirectly in:
- Request: Parameter Object, Request Body Object, Header Object
- Response: Header Object, Response Object
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, formatcombination 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,anyOfproperty, combine them first then do checkmultipleOfproperty, 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 OASminimum,minLenght,minItems,minProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must be <= old OAS.exclusiveMaximum,exclusiveMinimumproperty, only allow changetrue(old)->false(new)uniqueItemsproperty, only allow changetrue(old)->false(new)requiredproperty, new OAS must == old OAS or new OAS is old OAS subsetenumproperty, new OAS must == old OAS or new OAS is old OAS supersetpropertiesproperty, new OAS could add or delete property name(propertieskey)nullableproperty, only allow changefalse(old)->true(new)discriminatorproperty, new and old must be identicalxmlproperty, new and old must be identicalreadOnly,writeOnlyproperty, 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, formatcombination 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,anyOfproperty, combine them first then do checkmultipleOfproperty 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 OASminimum,minLenght,minItems,minProperties, if old OAS is null, then new OAS must be null too. Otherwise, new OAS must >= old OASexclusiveMaximum,exclusiveMinimumproperty, only allow changefalse(old)->true(new)uniqueItemsproperty, only allow changefalse(old)->true(new)requirednew OAS must == old OAS or new OAS is old OAS supersetenumproperty, new OAS must == old OAS or new OAS is old OAS subsetpropertiesproperty, new OAS could add or delete property name(propertieskey)nullableproperty , only allow changetrue(old)->false(new)discriminatorproperty, new and old must be identicalxmlproperty, new and old must be identicalreadOnly,writeOnlyproperty, new and old must be identical
Encoding Object doc
Notice: Encoding Object only apply to Request Body Object
contentTypeproperty, new and old must be identicalheadersproperty, new OAS can not add new he header name (headerskey), but and delete header namestyleproperty, new and old must be identicalexplodeproperty, new and old must be identicalallowReservedproperty, only allow changefalse(old) -> true(new)
Header Object doc
schemaproperty, see Schema Object compatibility check rules
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.