【问题标题】:Swagger: variant schema shape dependant on field valueSwagger:依赖于字段值的变体模式形状
【发布时间】:2017-10-04 04:35:59
【问题描述】:

我有一个模型定义为:

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 中定义差异(见下文),但这不起作用。

如您所见,下面显示了三个示例,每个示例都因type 而不同。这就是 API 的行为方式,但记录这种预期行为并不简单。

  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

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

【问题讨论】:

  • 在您的第二个示例中,标量的每个折叠样式指示符 (>) 都是多余的,并且使您的 YAML 不必要地不可读。那是因为这些标量都不是由多行组成的,而且对于其中许多甚至是不可能的。这是关于如何执行 YAML 的一个很好的例子
  • 很公平。对实际问题没有帮助?
  • 我对swagger一无所知,我是因为(IMO放错位置)yaml标签而来到这里的。

标签: swagger swagger-2.0


【解决方案1】:

这可以使用model inheritance/compositiondiscriminator 来实现。

首先,定义仅包含公共属性的基本模型Event,并将type 属性标记为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 来覆盖显示的模型名称。

  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) 作为请求或响应架构:

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

客户端应检查鉴别器属性的值(在本例中为type)以决定使用哪个继承模型。

Swagger UI 用户注意事项: Swagger UI 和 Swagger Editor 目前不支持基于 discriminator 的切换模型。关注this issue 获取更新。


OpenAPI 3.0 中,这更容易 - 您可以简单地使用 oneOf 为请求或响应定义备用架构。

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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2014-12-01
    • 2019-03-11
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多