Swagger:取决于字段值的变体模式形状 [英] Swagger: variant schema shape dependant on field value
问题描述
我有一个模型定义为:
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
模型继承点击/打开/发送模型.子模型的名称必须与鉴别器属性的值相同.在您的示例中,模型必须命名为 click
、open
和 sent
.如果您使用 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屋!