【问题标题】:Tell Swagger that the request body can be a single object or a list of objects告诉 Swagger 请求正文可以是单个对象或对象列表
【发布时间】:2015-07-31 09:00:45
【问题描述】:

我正在使用 Swagger 和 Scala 来记录我的 REST API。我想为 POST、PUT 和 DELETE 启用批量操作,并希望相同的路由接受单个对象或对象集合作为正文内容。

有没有办法告诉 Swagger 参数是 A 类型值的列表或 A 类型的单个值?

类似于 REST 的可变参数。

【问题讨论】:

    标签: scala rest swagger openapi


    【解决方案1】:

    有没有办法告诉 Swagger 参数是 A 类型值的列表或 A 类型的单个值?

    这取决于您使用的是 OpenAPI 3.0 还是 OpenAPI (Swagger) 2.0。

    OpenAPI 使用 JSON Schema 的扩展子集来描述正文负载。 JSON Schema 提供了oneOfanyOf 关键字来为一个实例定义多个可能的模式。但是,不同版本的 OpenAPI 支持不同的 JSON Schema 关键字集。

    OpenAPI 3.0 支持oneOfanyOf,因此您可以如下描述这样的对象或对象数组:

    openapi: 3.0.0
    ...
    
    components:
      schemas:
        A:
          type: object
        Body:
          oneOf:
            - $ref: '#/components/schemas/A'
            - type: array
              items:
                $ref: '#/components/schemas/A'
    

    在上面的示例中,Body 可以是对象 A 或对象数组 A

    OpenAPI (Swagger) 2.0 does not support oneOf and anyOf。您最多可以使用typeless schema

    swagger: '2.0'
    ...
    
    definitions:
      A:
        type: object
      # Note that Body does not have a "type"
      Body:
        description: Can be object `A` or an array of `A`
    

    这意味着Body 可以是任何东西——一个对象(任何对象!)、一个数组(包含任何项目!),也可以是一个基元(字符串、数字等)。在这种情况下,无法定义确切的 Body 结构。您只能在description 中口头描述。

    您需要使用 OpenAPI 3.0 来定义您的确切场景。

    【讨论】:

    • 感谢您挖掘它。这是一个公认的缺点,希望将来会受到一些关注,因为它确实妨碍了对 GeoJSON 等现有 API 的正确文档。此链接添加到讨论中:github.com/swagger-api/swagger-spec/issues/57 我想现在我只会用文字正确记录“列表或单个对象”样式。
    【解决方案2】:

    我不知道是否可以使用 Swagger 像那样注释您的 API。但我的建议是简化/统一您的 API。如果您考虑一下,如果您要支持批量(即一组对象),那么没有理由对单个对象进行特殊处理。您应该只更改 API 以始终采用数组,如果有人想做单个对象,那么这只是具有单个元素 object :: Nil 的列表的情况。

    【讨论】:

    • ... 正好需要两个字符:[]
    【解决方案3】:

    如果要发送对象,只需删除 @OA\Items()

     *   @OA\RequestBody(
     *      required=true,
     *      @OA\JsonContent(
     *         ref="#/components/schemas/Brand"
     *      )
     *   ),
    

    【讨论】:

      最近更新 更多