如何在OpenAPI(Swagger)中为相同的HTTP状态代码定义不同的响应?

时间:2017-11-23 04:07:10

标签: swagger openapi

我正在为现有的API编写OpenAPI规范。此API返回成功和失败的状态200,但具有不同的响应结构。

例如,在注册API中,如果用户成功注册,则API会使用以下JSON发送状态200:

{
    "result": true,
    "token": RANDOM_STRING
}

如果有重复的用户,API也会发送状态200,但使用以下JSON:

{
    "result": false,
    "errorCode": "00002", // this code is duplicated error
    "errorMsg": "duplicated account already exist"
}

在这种情况下,如何定义响应?

2 个答案:

答案 0 :(得分:8)

这可以在OpenAPI 3.0中实现,但不能在2.0中实现。

OpenAPI 3.0支持oneOf,用于为响应指定备用架构。您还可以添加多个响应examples,例如成功和失败的响应(但是,Swagger UI中的多个examples当前为not displayed

openapi: 3.0.0
...

paths:
  /something:
    get:
      responses:
        '200':
          description: Result
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ApiResultOk'
                  - $ref: '#/components/schemas/ApiResultError'
              examples:
                success:
                  summary: Example of a successful response
                  value:
                    result: true
                    token: abcde12345
                error:
                  summary: Example of an error response
                  value:
                    result: false
                    errorCode: "00002"
                    errorMsg: "duplicated account already exist"

components:
  schemas:
    ApiResultOk:
      type: object
      properties:
        result:
          type: boolean
          enum: [true]
        token:
          type: string
      required:
        - result
        - token
    ApiResultError:
      type: object
      properties:
        result:
          type: boolean
          enum: [false]
        errorCode:
          type: string
          example: "00002"
        errorMsg:
          type: string
          example: "duplicated account already exist"

在OpenAPI / Swagger 2.0中,每个响应代码只能使用一个模式,因此您可以做的最多的事情是将变化字段定义为可选字段,并在模型description或操作{{1中记录它们的用法}}

description

答案 1 :(得分:0)

如果您的响应恰好是array类型的,或者具有相同的结构,并且在array类型的节点之下的一个节点中有所不同,那么即使在swagger 2.0中也可以这样做。就是会为这些工作:

[                                                                               
    {                                                                              
        "anything": 1                                                              
    },                                                                             
    {                                                                              
        "anything other": 2                                                        
    }                                                                              
]

{
  "errors": [
    {
      "code": "ERR_NO_CONTRACT",
      "error_message": "No contract found",
      "parameters": [],
      "placeholders": []
    }
  ]
}

等等。只需定义通用结构,并在数组定义中使用enum就可以了,

swagger: '2.0'
info:
  version: v1
  title: title
definitions:
  MultiError400:
    type: array
    required:
      - errors
    items:
      type: object
      enum:
      - $ref: '#/definitions/FirstError'
      - $ref: '#/definitions/SecondError'
  FirstError:
    type: object
    required:
      - code
    properties:
      code:
        type: string
  SecondError:
    type: object
    required:
      - code
    properties:
      code:
        type: string
paths:
  /path:
    parameters:
      - name: name
        description: blah blah
        in: query
        required: true
        type: string
    post:
      consumes:
        - application/json
      responses:
        '400':
          description: Multiple 400 errors
          schema:
            $ref: '#/definitions/MultiError400'