OpenAPI 3.0.x中如何定义请求Schema的互斥JSON对象?
实现OpenAPI中两个JSON对象的互斥约束
你需要在OpenAPI 3.0.1契约中让parent下的child3和child4不能同时出现在请求中,且Swagger Codegen能对违规请求返回400 Bad Request。你用oneOf的思路是对的,但之前的写法存在位置错误——oneOf是Schema的顶级关键字,不能放在properties字段里,必须和properties、type等关键字同级。
错误写法的问题
你之前把oneOf嵌套在parent的properties中,这不符合OpenAPI规范,properties里只能定义对象的属性名和对应Schema,不能直接放置oneOf这类约束关键字。
正确的OpenAPI 3.0.1契约写法
以下是修正后的完整契约,实现child3和child4的互斥约束(允许只出现其中一个、或都不出现,但禁止同时出现):
{ "openapi": "3.0.1", "info": { "title": "Example API with Grandparents", "version": "1.0.0" }, "paths": { "/example": { "post": { "summary": "Endpoint with mutually exclusive objects under grandparent", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "grandparent": { "type": "object", "required": ["parent"], "properties": { "parent": { "type": "object", "properties": { "child1": { "type": "object", "properties": { "grandChild1": { "$ref": "#/components/schemas/GrandChild1" } } }, "child2": { "type": "object", "properties": { "grandChild2": { "$ref": "#/components/schemas/GrandChild2" } } }, "child3": { "type": "object", "properties": { "grandChild3": { "$ref": "#/components/schemas/GrandChild3" } } }, "child4": { "type": "object", "properties": { "grandChild4": { "$ref": "#/components/schemas/GrandChild4" } } } }, // 核心约束:禁止同时存在child3和child4 "not": { "required": ["child3", "child4"] }, // 可选:如果要求必须出现child3或child4中的一个,取消以下注释 // "oneOf": [ // { "required": ["child3"] }, // { "required": ["child4"] } // ] } } } }, "required": ["grandparent"] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Success" } } } } } }, "400": { "description": "Bad Request - child3 and child4 cannot exist together" } } } } }, "components": { "schemas": { "GrandChild1": { "type": "string", "maxLength": 36 }, "GrandChild2": { "type": "string", "maxLength": 36 }, "GrandChild3": { "type": "string", "maxLength": 36 }, "GrandChild4": { "type": "string", "maxLength": 36 } } } }
约束说明
not关键字的作用:"not": { "required": ["child3", "child4"] }明确禁止请求同时包含child3和child4两个属性,满足你的核心需求。- 可选的
oneOf约束:如果业务要求必须在child3和child4中选填一个(不能都不出现),可以取消注释中的oneOf配置,强制请求必须包含其中一个属性。 - 400响应定义:显式添加
400响应后,Swagger Codegen生成的服务端代码会根据Schema验证结果,自动对违规请求返回该响应。
验证与Codegen支持
- 主流OpenAPI验证工具(如Swagger UI、Postman)都会识别该约束,对同时包含
child3和child4的请求标记为无效。 - Swagger Codegen生成的服务端代码会自动集成Schema验证逻辑,收到违规请求时直接返回400 Bad Request。
内容的提问来源于stack exchange,提问作者Vishnu
相关产品推荐
相关产品推荐

