【问题标题】:How to define mutually exclusive query parameters in Swagger (OpenAPI)?如何在 Swagger (OpenAPI) 中定义互斥查询参数?
【发布时间】:2014-02-03 17:19:16
【问题描述】:

我在Swagger中有一系列这样的参数

                    "parameters": [
                    {
                        "name": "username",
                        "description": "Fetch username by username/email",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    },
                    {
                        "name": "site",
                        "description": "Fetch username by site",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    },
                    {
                        "name": "survey",
                        "description": "Fetch username by survey",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    }
                ],

必须填写一个参数,但不管哪个参数,其他的可以留空。有没有办法在 Swagger 中表示这一点?

【问题讨论】:

  • 很遗憾没有,好像这个功能不可用

标签: swagger openapi


【解决方案1】:

OpenAPI 3.x 中可能存在(某种程度上)互斥参数:

  • 将互斥参数定义为对象属性,并使用oneOfmaxProperties 将对象限制为仅1 个属性。
  • 使用parameter serialization methodstyle: formexplode: true,使对象序列化为?propName=value

使用minPropertiesmaxProperties 约束的示例:

openapi: 3.0.0
...
paths:
  /foo:
    get:
      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            properties:
              username:
                type: string
              site:
                type: string
              survey:
                type: string
            minProperties: 1
            maxProperties: 1
            additionalProperties: false

使用oneOf:

      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            oneOf:
              - properties:
                  username:
                    type: string
                required: [username]
                additionalProperties: false
              - properties:
                  site:
                    type: string
                required: [site]
                additionalProperties: false
              - properties:
                  survey:
                    type: string
                required: [survey]
                additionalProperties: false

另一个使用oneOf的版本:

      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            properties:
              username:
                type: string
              site:
                type: string
              survey:
                type: string
            additionalProperties: false
            oneOf:
              - required: [username]
              - required: [site]
              - required: [survey]

请注意,Swagger UI 和 Swagger Editor 尚不支持上述示例(截至 2018 年 3 月)。 This issue好像覆盖了参数渲染部分。


OpenAPI 规范存储库中还有一个针对support interdependencies between query parameters 的公开提案,因此未来版本的规范可能会有更好的方法来定义此类场景。

【讨论】:

  • 我是否遗漏了一些明显的东西?因为这似乎没有对我在 aws 的 api 网关上做任何验证
  • @omega_prime AWS API Gateway doesn't support oneOf 和其他一些 OpenAPI 功能。
【解决方案2】:

很遗憾,目前这是不可能的。 "required" 只是一个布尔值,无法表示参数之间的相互依赖关系。

您能做的最好的就是在参数描述中明确要求,并按照相同的行添加自定义的 400 Bad Request 描述。

https://github.com/OAI/OpenAPI-Specification/issues/256 讨论了在下一版本的 OpenAPI 规范中实现此功能的可能方法。

【讨论】:

  • OpenAPI 3.0 有一种描述互斥参数的方法,参见this answer
【解决方案3】:

改变你的 API 设计怎么样? 目前你有一种方法,3个参数。如果我理解得很好,用户必须始终只提供一个参数,其余两个必须取消设置。

对我来说,API 会更适合三个端点——比如

/user/byName?name=
/user/bySite?name=
/user/bySurvey?name=

【讨论】:

  • 解决了技术问题,但不是很安静。
【解决方案4】:

另一种方法是传入一个带有枚举的过滤器类型参数,以及一个带有要使用的值的过滤器值。

例如:https://app.swaggerhub.com/api/craig_bayley/PublicAPIDemo/v1

您可以选择是否需要。但是,如果需要一个,它们都应该是。

【讨论】:

  • 我是否理解正确,在这种情况下,您的提案会产生 API /users?name=name&filterType=[name|site|survey] 吗?我同意,因为这更 Restfull,因为我们只有单一资源,它应该是(仍然有干净和可用的 API)。
猜你喜欢
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多