允许swagger查询参数为字符串或整数数组

时间:2016-12-21 21:00:26

标签: node.js swagger swagger-2.0 openapi

在使用swagger2(openAPI)构建rest api时,我想允许查询param 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。

1 个答案:

答案 0 :(得分:1)

我认为您需要的是anyOfoneOf关键字,类似于JSON Schema提供的关键字,因此您可以将station_id参数的类型定义为数字或字符串。 OpenAPI 3.0支持anyOfoneOf,但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个站点。