Swagger:取决于字段值的变体模式形状 [英] Swagger: variant schema shape dependant on field value

查看:41
本文介绍了Swagger:取决于字段值的变体模式形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型定义为:

Event:
  type: object
  properties:
    id:
      type: string
    timestamp:
      type: string
      format: date-time
    type:
      type: string
      enum:
        - click
        - open
        - sent
    click:
      type: object
      properties:
        url:
          type: string
        title:
          type: string
    open:
      type: object
      properties:
        subject:
          type: string
    sent:
      type: object
      properties:
        subject:
          type: string
        from:
          type: string
        to:
          type: string

然而,实际上根据 type 枚举字段的值,形状是不同的.它可以是三个之一,我试图定义 examples(见下文)中的差异,但这不起作用.

However, the shape is actually different depending on the value of the type enum field. It can be one of three, I tried to define the differences in the examples (see below) but this did not work.

如您所见,下面显示了三个示例,每个示例都因type 而异.这就是 API 的行为方式,但要记录这种预期行为并不容易.

As you can see, the below shows three examples, each one is different depending on the type. This is how the API behaves, but it is not straightforward to document this expected behaviour.

  examples:
    application/json:
      - id: >
          ad1b12f0-63a8-47b5-9820-3e447143ce7e
        timestamp: >
          2017-09-29T16:45:20.000+00:00
        type: click
        click:
          url: >
            www.some-website-somewhere.org/12345
          title: >
            Click here!
      - id: >
          d9e787fa-db49-4bd8-97c3-df45f159295c
        timestamp: >
          2017-09-29T16:45:20.000+00:00
        type: open
        open:
          subject: >
            Have you seen this?
      - id: >
          30adc194-0f5f-4889-abd4-4fa964d0bb42
        timestamp: >
          2017-09-29T16:45:20.000+00:00
        type: sent
        sent:
          subject: >
            Have you seen this?
          from: >
            bill@office.gov
          to: >
            mon@gmail.com

我读过一些地方提到这是不可能的,但我希望得到一些跳出框框"的思想家来帮助我找到解决方案.

I read a few places that mention this is not possible, but I am hoping to get some "outside the box" thinkers to help me find a solution.

推荐答案

这可以使用 模型继承/组合鉴别器.

This is possible using model inheritance/composition and discriminator.

首先,定义只包含公共属性的基本模型Event,并将type属性标记为discriminator:

First, define the base model Event that contains just the common properties, and mark the type property as discriminator:

definitions:
  Event:
    type: object
    discriminator: type
    required:
      - type  # discriminator property is required
    properties:
      id:
        type: string
        example: ad1b12f0-63a8-47b5-9820-3e447143ce7e
      timestamp:
        type: string
        format: date-time
        example: 2017-09-29T16:45:20.000+00:00
      type:
        type: string
        enum:
          - click
          - open
          - sent

然后通过 allOf 从基础 Event 模型继承点击/打开/发送模型.子模型的名称必须与鉴别器属性的值相同.在您的示例中,模型必须命名为 clickopensent.如果您使用 Swagger UI,则可以添加 title 以覆盖 显示的 模型名称.

Then inherit the click/open/sent models from the base Event model via allOf. The names of the child models must be the same as the values of the discriminator property. In your example, the models must be named click, open and sent. If you use Swagger UI, you can add title to override the displayed model names.

  click:
    title: ClickEvent
    allOf:
      - $ref: '#/definitions/Event'
      - type: object
        properties:
          click:
            type: object
            properties:
              url:
                type: string
                example: www.some-website-somewhere.org/12345
              title:
                type: string
                example: Click here!

在操作中,使用基本模型(Event)作为请求或响应模式:

In operations, use the base model (Event) as the request or response schema:

responses:
  200:
    description: OK
    schema:
      $ref: '#/definitions/Event'

客户应该检查鉴别器属性的值(在这个例子中 - type)来决定使用哪个继承模型.

The clients should examine the value of the discriminator property (in this example - type) to decide which inherited model to use.

Swagger UI 用户注意事项: Swagger UI 和 Swagger Editor 目前不支持基于 discriminator 的切换模型.关注此问题以获取更新.

Note for Swagger UI users: Swagger UI and Swagger Editor currently do not support switching models based on discriminator. Follow this issue for updates.


OpenAPI 3.0 中更容易 - 您只需使用 oneOf 来定义请求或响应的替代模式.


In OpenAPI 3.0 it's easier - you can simply use oneOf to define alternate schemas for a request or response.

responses:
  '200':
    description: OK
    content:
      application/json:
        schema:
          oneOf:
            - $ref: '#/components/schemas/ClickEvent'
            - $ref: '#/components/schemas/OpenEvent'
            - $ref: '#/components/schemas/SentEvent'
          # Optional mapping of `type` values to models
          discriminator:
            propertyName: type
            mapping:
              click: '#/components/schemas/ClickEvent'
              open:  '#/components/schemas/OpenEvent'
              sent:  '#/components/schemas/SentEvent'

这篇关于Swagger:取决于字段值的变体模式形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆