OpenAPI v3中能否根据属性值强制匹配对应Schema?
OpenAPI v3 能否根据对象属性值强制匹配对应Schema?
给定以下OpenAPI V3 Schema:
openapi: 3.0.0 info: title: Animals API version: 1.0.0 paths: /v1/animals: post: requestBody: description: Animal required: true content: application/json: schema: type: object properties: animal: type: string enum: - cat - dog payload: oneOf: - $ref: '#/components/schemas/DogSchema' - $ref: '#/components/schemas/CatSchema' responses: 201: description: Created 400: description: Bad request components: schemas: DogSchema: type: object properties: dogProperty1: type: string dogProperty2: type: integer CatSchema: type: object properties: catProperty1: type: string catProperty2: type: boolean
需求是:指定当animal属性值为dog时,payload必须符合DogSchema;当animal为cat时,payload必须符合CatSchema,使得如下请求体被判定为无效请求(返回如422状态码):
{ "animal": "cat", "payload": { "dogProperty1": "some value", "dogProperty2": 0 } }
完全可以实现这个需求,你需要利用OpenAPI 3.0支持的条件验证规则,将animal字段的取值与payload的Schema做绑定,替代原来payload单独的oneOf定义。
修改后的完整Schema
可以通过oneOf结合const关键字定义两个互斥的合法请求体结构,确保animal和payload的匹配关系:
openapi: 3.0.0 info: title: Animals API version: 1.0.0 paths: /v1/animals: post: requestBody: description: Animal required: true content: application/json: schema: type: object required: [animal, payload] # 定义两个互斥的合法结构 oneOf: - properties: animal: const: dog # 强制animal为dog payload: $ref: '#/components/schemas/DogSchema' - properties: animal: const: cat # 强制animal为cat payload: $ref: '#/components/schemas/CatSchema' responses: 201: description: Created 400: description: Bad request 422: description: Validation error components: schemas: DogSchema: type: object required: [dogProperty1, dogProperty2] properties: dogProperty1: type: string dogProperty2: type: integer CatSchema: type: object required: [catProperty1, catProperty2] properties: catProperty1: type: string catProperty2: type: boolean
验证逻辑说明
oneOf要求请求体必须严格匹配其中一个分支的定义,既不能同时符合多个,也不能都不符合- 每个分支用
const固定animal的取值,同时绑定对应的payloadSchema - 当请求体中
animal为cat但payload使用DogSchema结构时,会因不匹配任何oneOf分支触发验证失败,此时API网关或验证工具会返回类似422的错误响应
如果需要更灵活的条件判断,也可以用if/then/else关键字实现相同逻辑:
schema: type: object required: [animal, payload] properties: animal: type: string enum: [cat, dog] # 当animal为dog时,payload必须符合DogSchema if: properties: animal: const: dog then: properties: payload: $ref: '#/components/schemas/DogSchema' # 否则检查是否为cat,对应CatSchema else: if: properties: animal: const: cat then: properties: payload: $ref: '#/components/schemas/CatSchema'
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

