当前位置: 首页 > 知识库问答 >
问题:

Swagger:依赖于字段值的变体模式形状

朱硕
2023-03-14

我有一个模型定义为:

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

但是,根据< code>type枚举字段的值,形状实际上是不同的。它可以是三个中的一个,我试图在< code >示例(见下文)中定义不同之处,但这不起作用。

如您所见,下面显示了三个示例,每个示例都因类型而异。这是 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

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

共有1个答案

夏骏
2023-03-14

这可以使用模型继承/组合和< code >鉴别器来实现。

首先,定义仅包含公共属性的基本模型< code>Event,并将< code>type属性标记为< code>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

然后通过< code>allOf从基本< code>Event模型继承点击/打开/发送模型。子模型的名称必须与discriminator属性的值相同。在您的示例中,模型必须命名为< code>click、< code>open和< code>sent。如果您使用Swagger UI,您可以添加< code>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!

在操作中,使用基本模型(事件)作为请求或响应架构:

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

客户端应该检查discriminator属性(在本例中为< code>type)的值,以决定使用哪个继承模型。

Swagger UI用户注意:Swagger UI和Swagger编辑器目前不支持基于< code>discriminator切换模型。请关注此问题以获取更新。


在 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'
 类似资料:
  • 我在Ubuntu中编译了OpenJDK,并在我们的嵌入式系统(linux的风格)中删除了JRE包。OpenJDK没有可再发行的字体。我在jre/lib/fonts目录中删除了dejavu字体。 如果我将Lucida字体(与Sun/OracleJRE一起发布)复制到JRE/lib/fonts,我的应用程序运行良好。 请告诉我在openjdk中使用Dejavu字体的步骤,

  • 有时候,希望一篇文章中的英文单词或英文字母,无论是小写还是大写,统一变成大写,就可以使用 font-variant属性实现。 font-variant属性用来使英文字母变为小型大写字母,可选值有 normal | small-caps,默认值为 normal。normal 为正常的字体;small-caps 让字母变成小型大写字母,这意味着所有的小写字母均会被转换为大写,但字体更小。如: .nor

  • 我有4个输入字段如下。名称,计数,金额,价格。和两个文本字段,佣金和总额。 如果用户输入价格和计数值,则应计算金额(价格*计数)。如果用户输入价格和金额值,则应计算计数(金额/价格)。在这两种情况下,佣金=0.02*金额和总额=金额佣金都应更新。 所以,我尝试了下面的代码片段作为根据价格更新金额和佣金的开始。但是它没有更新。 //应用程序。js //createCoins.jsx 你能推荐一下吗。

  • 问题内容: 我有一个表格,其中的两个字段根据需要在我不希望出现时也出现。这是来自models.py的表格 在实际的电路模型中,字段的定义如下: 我的views.py在这里: 我该怎么做,以便不需要这两个字段? 问题答案: 如果您不想修改模型中字段的空白设置(这样做会破坏管理站点中的常规验证),则可以在Form类中执行以下操作: 重新定义的构造函数不会损害任何功能。

  • 问题内容: 有一个表格,其中的两个字段在我也不希望出现时按要求列出。这是来自models.py的表格 我的views.py在这里: 我该怎么做,以便不需要这两个字段? 问题答案: 如果你不想修改模型中字段的空白设置(这样做将破坏管理站点中的常规验证),则可以在Form类中执行以下操作: 重新定义的构造函数不会损害任何功能。

  • 问题 是否可以创建一个动态ValueRangeProvider,其值范围取决于规划变量的当前值?或者有什么其他的方法可以达到这种想要的效果? 轮班需要分配员工,以便尽可能多地覆盖轮班的持续时间 员工只能在每个轮班和每个员工唯一的特定时间内开始 员工和他们的开始时间都需要作为严格的硬约束进行优化(员工不能被安排到没有可用时间的班次,而且开始时间也不能超出该员工在该班次的可用时间) 员工工作的持续时间