【问题标题】:Allow swagger query param to be array of strings or integers允许 swagger 查询参数为字符串或整数数组
【发布时间】:2016-12-21 21:00:26
【问题描述】:

在使用 swagger2 (openAPI) 构建 rest api 时,我希望允许查询参数 station_id 支持以下内容:

  • ?station_id=23(返回站 23)
  • ?station_id=23,45(返回站 23 和 45)
  • ?station_id=[3:14](返回站 3 到 14)
  • ?station_id=100%(%s 充当通配符,因此返回 1001 之类的内容, 10049 等)

我使用以下 swagger 定义(字符串数组)来尝试完成此操作:

parameters:
  - name: station_id
    in: query
    description: filter stations by station_id
    required: false
    type: array
    items:
      type: string

使用此定义,除 ?station_id=23 之外的所有先前示例都有效,因为 swagger 验证失败并显示以下消息:

{
  "message": "Validation errors",
  "errors": [
    {
      "code": "INVALID_REQUEST_PARAMETER",
      "errors": [
        {
          "code": "INVALID_TYPE",
          "params": [
            "array",
            "integer"
          ],
          "message": "Expected type array but found type integer",
          "path": [],
          "description": "filter stations by station_id"
        }
      ],
      "in": "query",
      "message": "Invalid parameter (station_id): Value failed JSON Schema validation",
      "name": "station_id",
      "path": [
        "paths",
        "/stations",
        "get",
        "parameters",
        "0"
      ]
    }
  ]
}

请注意,如果我引用 station_id 像 ?station_id='23' 验证通过,我会得到正确的响应。但我真的不想使用引号。像联合类型这样的东西可以帮助解决这个问题,但据我所知,它们不受支持。

我还有另一个端点 /stations/{id} 可以处理单个 id 的情况,但仍然有许多其他(非主键)数字字段我想以上面指定的方式过滤。例如 station_latitude。

任何解决方法的想法 - 也许我可以以某种方式使用模式(正则表达式)?如果在 swagger 定义中没有解决方法,是否有办法调整或绕过验证器?这是一个使用swagger-node的nodejs项目我已经将swagger-express-mw的版本升级到0.7.0。

【问题讨论】:

    标签: node.js swagger swagger-2.0 openapi


    【解决方案1】:

    我认为您需要的是类似于 JSON Schema 提供的 anyOfoneOf 关键字,以便您可以将 station_id 参数的类型定义为数字或字符串。 anyOfoneOf 在 OpenAPI 3.0 中受支持,但在 2.0 中不支持。 OpenAPI 3.0 定义如下所示:

    openapi: 3.0.0
    ...
    paths:
      /something:
        get:
          parameters:
            - in: query
              name: station_id
              required: true
              explode: false
              schema:
                oneOf:
                  - type: integer # Optional? Array is supposed to cover the use case with a single number
                    example: 23
                  - type: array
                    items:
                      type: integer
                    minItems: 1
                    example: [23, 45]
                  - type: string
                    oneOf:
                      - pattern: '^\[\d+:\d+]$'
                      - pattern: '^\d+%$'
                    # or using a single pattern
                    # pattern: '^(\[\d+:\d+])|(\d+%)$'
                    example: '[3:14]'
    


    作为替代方案,也许您可​​以添加sortByskiplimit 参数以使您保持类型统一。例如:?sortBy=station_id&skip=10&limit=10 将只检索站 10 - 20。

    【讨论】:

    • OpenAPI v3 将支持 AnyOf
    猜你喜欢
    • 2017-09-14
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多