重复使用具有不同所需属性的模型

时间:2016-11-28 08:13:13

标签: swagger openapi

我有一个路径,它使用每个http方法具有几乎相同属性的复杂模型。问题是我想为PUT和POST的请求定义一些必需的属性,而GET响应中不需要属性(因为服务器总是返回所有属性,并且在文档的其他地方提到它)

我创建了一个简单的cat API来演示我尝试过的内容。我们的想法是,对于GET响应,响应模型没有标记为必需的任何内容,但PUT的请求必须具有猫的名称。

swagger: "2.0"

info:
  title: "Cat API"
  version: 1.0.0

paths:
  /cats/{id}:
    parameters:
      - name: id
        in: path
        required: true
        type: integer
    get:
      responses:
        200:
          description: Return a cat
          schema:
            $ref: "#/definitions/GetCat"
    put:
      parameters:
        - name: cat
          in: body
          required: true
          schema:
            $ref: "#/definitions/PutCat"
      responses:
        204:
          description: Cat edited

definitions:
  Cat:
    type: object
    properties:
      name:
        type: string
  GetCat:
    allOf:
      - $ref: "#/definitions/Cat"
    properties:
      id:
        type: integer
  PutCat:
    type: object
    required:
      - name
    properties:
      $ref: "#/definitions/Cat/properties"

Swagger编辑说这是一个有效的规范,但是name被设置为GET和PUT都需要。 Swagger UI也是如此。

我还尝试了以下版本的PutCat:

PutCat:
  type: object
  required:
    - name
  allOf:
    - $ref: "#/definitions/Cat"

但现在一切都是可选的。

我无法弄清楚这一点。有没有办法正确地做到这一点?

修改

正如Helen正确提到的那样,我可以使用readOnly来解决GET和PUT的这种特殊情况。

但是,假设我添加breed属性,必须为PUT提供(除name属性外)。然后我添加PATCH方法,可用于更新breedname而另一方保持不变,我想根据需要设置这两种方法。

2 个答案:

答案 0 :(得分:22)

在您的示例中,您可以将单个模型用于GET和POST / PUT,其中的属性仅在标记为readOnly的GET响应中使用。来自spec

  

readOnly

     

将属性声明为“只读”。这意味着它可以作为响应的一部分发送,但绝不能作为请求的一部分发送。标记为readOnly为true的属性不应位于已定义模式的必需列表中。默认值为false。

规范如下:

    get:
      responses:
        200:
          description: Return a cat
          schema:
            $ref: "#/definitions/Cat"
    put:
      parameters:
        - name: cat
          in: body
          required: true
          schema:
            $ref: "#/definitions/Cat"
      responses:
        204:
          description: Cat edited

definitions:
  Cat:
    properties:
      id:
        type: integer
        readOnly: true
      name:
        type: string
      breed:
        type: string
    required:
      - name
      - breed

这意味着您必须提出namebreed

{
  "name": "Puss in Boots",
  "breed": "whatever"
}

GET /cats/{id}必须返回namebreed,并且还可以返回id

{
  "name": "Puss in Boots",
  "breed": "whatever",
  "id": 5
}

答案 1 :(得分:1)

我遇到了类似的问题。原来我的缩进是错的。 以下语法应该有效:

PutCat:
  allOf:
    - $ref: "#/definitions/Cat"
    - type: object
      required: [name]