OpenAPI V3 Spec校验工具
项目结构
- oas-validator-core,核心API及骨架实现
- oas-validator-core-spring,骨架的Spring Boot Starter
- oas-validator-test,核心API的测试帮助类
- oas-validator-compliance,合规性校验实现
- oas-validator-compliance-spring,合规性校验的Spring Boot Starter
- oas-validator-compatibility,兼容性校验实现
- oas-validator-compatibility-spring,兼容性校验实现的Spring Boot Starter
- oas-validator-web,校验工具的操作UI
合规性校验
OAS必须符合OAS 3.0.2规范(比如属性的名称、REQUIED要求)。除此之外则是我们自己的定义的合规性检查。
一些字符串匹配规则
- Lower Camel Case:首字母小写的驼峰,对应的正则
^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$
- Upper Camel Case:首字母大写的驼峰,对应的正则
^[A-Z]([a-z0-9]+[A-Z]?)*$
- Upper Hyphen Case:单词首字母大写,多个单词用
-
连接,比如Content-Type
、Accept
、X-Rate-Limit-Limit
。对应的正则:^([A-Z][a-z0-9]*-)*([A-Z][a-z0-9]*)$
OpenAPI Object doc
openapi
属性必须为3.0.x且>=3.0.2info
属性见Info Object合规性检查paths
属性,必须提供见Paths Object合规性检查components
属性见Components Object合规性检查tags
属性,至少提供一个Tag Objectsecurity
属性,不允许提供
Info Object doc
description
属性,必须填写
Tag Object doc
name
属性,必须是Upper Camel Casedescription
属性,必须填写- 不得存在Operation Object没有引用过的tag
Paths Object doc
- path必须是Lower Camel Case,包括Path Templating中的变量
Path Item Object doc
get/post/put/delete/...
属性,见Operation Object合规性检查parameters
属性,见Parameter Object合规性检查
Operation Object doc
summary
属性、必须填写operationId
属性,且Lower Camel Caseparameters
属性,见Parameter Object合规性检查requestBody
属性,见Request Body Object合规性检查responses
属性,见Responses Object合规性检查-
tags
属性,且只能写一个tag,且必须在OpenAPI Object 的tags
属性里所定义的范围内 servers
属性,不允许提供
Parameter Object doc
description
属性,必须填写name
属性- 如果
in
为path、query、cookie,则那么必须是Lower Camel Case - 如果
in
为header,则那么必须是Upper Hyphen Case
- 如果
schema
属性,见Schema Object合规性检查content
属性,见Media Type Object合规性检查
Request Body Object doc
description
属性,必须填写content
属性,见Media Type Object合规性检查
Media Type Object doc
schema
属性,必须填写。见Schema Object合规性检查encoding
属性,见Encoding Object合规性检查
Responses Object doc
Response Object doc
description
属性,必须填写headers
属性,name(headers
的key)必须是Upper Hyphen Casecontent
属性,见Media Type Object合规性检查
Schema Object doc
title
属性,如果上级是Schema Object或Components Object,那么必须填写properties
属性,name(properties
的key)必须是Lower Camel Case- Sub Schema见Schema Object合规性检查
Encoding Object doc
headers
属性,name(headers
的key)必须是Upper Hyphen Case
Header Object doc
description
属性,必须填写schema
属性,见Schema Object合规性检查content
属性,见Media Type Object合规性检查
Components Object doc
schemas
属性,name必须是Upper Camel Caseresponses
属性,name必须是Upper Camel Caseparameters
属性,name必须是Upper Camel Caseexamples
属性,name必须是Upper Camel CaserequestBodies
属性,name必须是Upper Camel Caseheaders
属性,name必须是Upper Hyphen Caselinks
属性,name必须是Upper Camel Casecallbacks
属性,name必须是Upper Camel Case
兼容性检查
对新旧两个版本的OAS做兼容性检查。
OAS可以使用Reference Object来描述Spec,两个不同的OAS会出现描述不同但语义相同的情况。比如下面的旧OAS没有使用Reference Object,而新OAS则使用了的情况:
旧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
新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
因此在检查兼容性的时候会将新旧OAS的Reference Object做解析,然后再检查,下面是一段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);
因此,检查下来如果发现不兼容,那么所报告的位置会和原文档有所不同。
Paths Object doc
- 新OAS必须包含旧OAS的所有的
path
,如果path
使用了Path Templating,只要变量名发生了变化,那么即使语义上相同也会被认为不同,比如/pets/{foo}
和/pets/{bar}
会被认定为不同。
Path Item Object doc
- 新OAS必须包含旧OAS的所有的get/put/post/delete/…Operation Object
Operation Object doc
operationId
属性,新旧OAS必须完全一致。parameters
属性,对它检查须在考虑到Path Item Object parameters属性的情况下进行:- 新OAS可以新增Parameter Object,但是新增的Parameter Object的
required
属性必须为false
- 新OAS可以删除Parameter Object
- 针对单个Parameter Object的修改的检查见Parameter Object兼容性检查(在同一个Operation Object下Parameter Object依靠
name
和in
两个属性作为ID)。
- 新OAS可以新增Parameter Object,但是新增的Parameter Object的
requestBody
属性,见Request Body Object兼容性检查responses
属性,见Responses Object兼容性检查
Parameter Object doc
required
属性,只允许true(旧) -> false(新)
allowEmptyValue
属性,只允许false(旧) -> true(新)
的变化style
属性,新旧OAS必须保持一致explode
属性,新旧OAS必须保持一致allowReserved
属性,只允许false(旧) -> true(新)
的变化schema
属性,见Schema Object兼容性检查content
属性,新OAS必须包含旧OAS的所有media type(content
的key),且不能新增media type
Request Body Object doc
content
属性,新OAS必须包含旧OAS的所有media type(content
的key)required
属性,只允许true(旧) -> false(新)
的变化
Media Type Object doc
schema
属性,见Schema Object兼容性检查encoding
属性,该属性仅适用于requestBody
,因此新旧OAS的property name(encoding
的key)必须完全一致
Responses Object doc
default
属性,如果旧OAS没有定义default
,那么新OAS也不能定义default
。{Http Status Code}
属性,新OAS不允许新增。- 见Response Object兼容性检查
Response Object doc
headers
属性,新OAS必须包含旧OAS的所有header name(headers
的key),可以新增header namecontent
属性,新OAS必须包含旧OAS的所有media type(content
的key),可以新增media type
Schema Object doc
OAS中定义,Schema Object可以直接或间接用在:
不同用途的兼容性检查规则有所不同。
用做请求时
原则上,当Schema Object用在请求时,只允许从紧到松的变化。
type, format
组合所允许的变化范围
旧(type,format) | 新(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
属性,在combine之后再做检查multipleOf
属性,如果旧OAS为null。新OAS必须==旧OAS或者新OAS是旧OAS的因子,比如6(旧)->3(新)maximum
、maxLength
、maxItems
、maxProperties
,如果旧OAS为null,那么新OAS也必须是null。其他情况,新OAS必须>=旧OAS。minimum
、minLenght
、minItems
、minProperties
,如果旧OAS为null,那么新OAS也必须是null。其他情况,新OAS必须<=旧OAS。exclusiveMaximum
、exclusiveMinimum
属性,仅允许true(旧)->false(新)
的变化uniqueItems
属性,只允许true(旧)->false(新)
的变化。required
属性,新OAS必须==旧OAS,或者新OAS是旧OAS的子集。enum
属性,新OAS必须==旧OAS,或者新OAS是旧OAS的超集。properties
属性,新OAS可以新增property name(properties
的key)或者减少property name。nullable
属性,只允许false(旧)->true(新)
的变化。discriminator
属性,新旧OAS必须完全一致。xml
属性,新旧OAS必须完全一致。readOnly
、writeOnly
,新旧OAS必须完全一致。
用做响应时
原则上,当Schema Object用在响应时,只允许从松到紧的变化。
type, format
组合所允许的变化范围
旧(type,format) | 新(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
属性,在combine之后再做检查multipleOf
属性,如果旧OAS为null。新OAS必须==旧OAS或者新OAS是旧OAS的倍数,比如3(旧)->6(新)maximum
、maxLength
、maxItems
、maxProperties
,如果旧OAS为null,那么新OAS也必须是null。其他情况,新OAS必须<=旧OAS。minimum
、minLenght
、minItems
、minProperties
,如果旧OAS为null,那么新OAS也必须是null。其他情况,新OAS必须>=旧OAS。exclusiveMaximum
、exclusiveMinimum
属性,仅允许false(旧)->true(新)
的变化uniqueItems
属性,只允许false(旧)->true(新)
的变化。required
属性,新OAS必须==旧OAS或者,新OAS是旧OAS的超集。enum
属性,新OAS必须==旧OAS,或者新OAS是旧OAS的子集。properties
属性,新OAS可以新增property name(properties
的key)或者减少property name。nullable
属性,只允许true(旧)->false(新)
的变化。discriminator
属性,新旧OAS必须完全一致。xml
属性,新旧OAS必须完全一致。readOnly
、writeOnly
,新旧OAS必须完全一致。
Encoding Object doc
PS. Encoding Object仅针对Request Body Object有用
contentType
属性,新旧OAS必须保持一致headers
属性,新OAS不能新增旧OAS的header name(headers
的key),但是可以删除header namestyle
属性,新旧OAS必须保持一致explode
属性,新旧OAS必须保持一致allowReserved
属性,只允许false(旧) -> true(新)
的变化
Header Object doc
schema
属性,见Schema Object兼容性检查
Components Object doc
Components Object定义的都是可复用OAS Object,而在检查兼容性的时候所有$ref
都已被解析了,因此不需要对Components Object的属性做兼容性检查。