OpenAPI 3.0多oneOf组定义验证异常,求正确响应Schema写法
如何编写符合要求的OpenAPI 3.0 Schema
需求明确
需要定义的响应体为JSON对象数组,每个数组元素(对象)必须满足两个条件:
- 必须包含
measured_at或time_bucket字段,二选一,不能同时存在也不能都不存在 - 必须包含以下三组数据中的一组,三组互斥:
- 单独的
value字段 latitude、longitude、altitude三个字段的完整组合running、walking两个字段的完整组合
- 单独的
问题分析
你之前的两种写法都存在核心问题:
- 第一种用
allOf组合时间字段的oneOf和所有数据字段的properties,导致所有数据字段被合并到同一对象,无法实现“三组选其一”的互斥要求 - 第二种把时间字段和数据字段组都放入同一个
oneOf,导致时间字段和数据字段被拆分为独立对象,不符合“每个对象同时包含时间字段和一组数据字段”的要求
正确的Schema写法
以下是符合要求的OpenAPI 3.0 YAML Schema:
components: schemas: Measurement: type: object allOf: # 时间字段二选一,互斥约束 - oneOf: - type: object required: [measured_at] properties: measured_at: type: string format: date-time additionalProperties: false - type: object required: [time_bucket] properties: time_bucket: type: string format: date-time # 若为时间戳桶可改为type: integer additionalProperties: false # 数据字段组三选一,互斥约束 - oneOf: # 单value字段组 - type: object required: [value] properties: value: type: number # 根据实际业务调整为integer/string等类型 additionalProperties: false # 经纬度海拔组 - type: object required: [latitude, longitude, altitude] properties: latitude: type: number format: float longitude: type: number format: float altitude: type: number format: float additionalProperties: false # 跑步/步行状态组 - type: object required: [running, walking] properties: running: type: boolean walking: type: boolean additionalProperties: false # 禁止对象包含未定义的额外字段 additionalProperties: false # 最终的响应体Schema MeasurementResponse: type: array items: $ref: '#/components/schemas/Measurement'
关键说明
- 使用
allOf将“时间字段二选一”和“数据组三选一”两个约束合并,确保每个对象同时满足这两个条件 - 每个
oneOf内部的子Schema都设置additionalProperties: false,避免跨组字段被混入(比如同时出现value和latitude) - 最外层的
additionalProperties: false防止出现未定义的额外字段 - 每个子Schema明确
required字段,确保必填项不缺失
内容的提问来源于stack exchange,提问作者BEANB00ZLED
相关产品推荐
相关产品推荐

