Open API 3.0参数依赖性:如果类型为“其中之一”带有共享参数,则为必需参数

问题描述

我正在创建一个openapi.json(版本3.0.3)架构,并且正在对发布请求进行建模。身体看起来像这样:

{
  type: "A",aParam: "string",sharedParam1: "string",sharedParam2: "integer",sharedParam3: "string"
}

其中typeAB之一。如果类型为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"
          }
        }
      }
    }
  }
}