问题描述
我正在创建一个openapi.json
(版本3.0.3)架构,并且正在对发布请求进行建模。身体看起来像这样:
{
type: "A",aParam: "string",sharedParam1: "string",sharedParam2: "integer",sharedParam3: "string"
}
其中type
是A
或B
之一。如果类型为A
,则必须排除参数aParam
,如果类型为B
aParam
。基本上,请求可以显示的另一种方式是:
{
type: "B",sharedParam3: "string"
}
如何建模?
这是我尝试过的:
{
"requestBody": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"type": "object","properties": {
"type": {
"type": "string","enum": ["A"]
},"aParam": {
"type": "string"
},"sharedParam1": {
"type": "string"
},"sharedParam2": {
"type": "string"
},"sharedParam3": {
"type": "string"
}
}
},{
"type": "object","enum": ["B"]
},"sharedParam3": {
"type": "string"
}
}
}
]
}
}
}
}
}
基本上,我通过使用oneOf
“重载”了请求正文,但这有很多重复。
解决方法
您可以将共享属性提取到基本架构。它不会使定义变得那么冗长,但至少会删除重复的属性定义,从而使它们更易于维护:
"components": {
"schemas": {
"baseRequestBody": {
"type": "object","required": [
"type","sharedParam1","sharedParam2","sharedParam3"
],"properties": {
"type": {
"type": "string","enum": [
"A","B"
]
},"sharedParam1": {
"type": "string"
},"sharedParam2": {
"type": "integer"
},"sharedParam3": {
"type": "string"
}
}
},"requestBodyA": {
"allOf": [
{
"$ref": "#/components/schemas/baseRequestBody"
},{
"type": "object","required": [
"aParam"
],"properties": {
"aParam": {
"type": "string"
}
}
}
]
},"requestBodyB": {
"allOf": [
{
"$ref": "#/components/schemas/baseRequestBody"
}
]
}
}
}
另外,您可能希望使用Discriminator,它可以由代码生成器之类的某些工具使用:
"requestBody": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/requestBodyA"
},{
"$ref": "#/components/schemas/requestBodyB"
}
],"discriminator": {
"propertyName": "type","mapping": {
"A": "#/components/schemas/requestBodyA","B": "#/components/schemas/requestBodyB"
}
}
}
}
}
}