跳到主要内容

Discriminator 对象

当一个 request bodies 或 response payloads 可以是多种 schemas 时,可以使用一个 discriminator 对象来帮助序列化、反序列化和校验。

The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.

当使用 discriminator 时,inline schemas 不会被考虑。

固定字段

字段名类型描述
propertyNamestring必选. 在 payload 中表示 discriminator 值的属性的名称。
mappingMap[string, string]一个映射 payload 中的值和 schema 名称  或引用的对象。

discriminator 属性仅在与 oneOf, anyOf, allOf 这几个复合关键字之一一起使用时才合法.

在 OAS 3.0 中,一个 response payload 仅可以使用一种类型来描述:

MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'

也就是说 payload 必须 且只能满足 CatDogLizzard schemas 中的一个。 In this case, a discriminator MAY act as a "hint" to shortcut validation and selection of the matching schema which may be a costly operation, depending on the complexity of the schema. We can then describe exactly which field tells us which schema to use:

MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
discriminator:
propertyName: pet_type

The expectation now is that a property with name pet_type MUST be present in the response payload, and the value will correspond to the name of a schema defined in the OAS document. Thus the response payload:

{
"id": 12345,
"pet_type": "Cat"
}

Will indicate that the Cat schema be used in conjunction with this payload.

In scenarios where the value of the discriminator field does not match the schema name or implicit mapping is not possible, an optional mapping definition MAY be used:

MyResponseType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
- $ref: 'https://gigantic-server.com/schemas/Monster/schema.json'
discriminator:
propertyName: pet_type
mapping:
dog: '#/components/schemas/Dog'
monster: 'https://gigantic-server.com/schemas/Monster/schema.json'

Here the discriminator value of dog will map to the schema #/components/schemas/Dog, rather than the default ( implicit) value of Dog. If the discriminator value does not match an implicit or explicit mapping, no schema can be determined and validation SHOULD fail. Mapping keys MUST be string values, but tooling MAY convert response values to strings for comparison.

When used in conjunction with the anyOf construct, the use of the discriminator can avoid ambiguity where multiple schemas may satisfy a single payload.

In both the oneOf and anyOf use cases, all possible schemas MUST be listed explicitly. To avoid redundancy, the discriminator MAY be added to a parent schema definition, and all schemas comprising the parent schema in an allOf construct may be used as an alternate schema.

For example:

components:
schemas:
Pet:
type: object
required:
- pet_type
properties:
pet_type:
type: string
discriminator:
propertyName: pet_type
mapping:
cachorro: Dog
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Cat`
properties:
name:
type: string
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Dog`
properties:
bark:
type: string
Lizard:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Lizard`
properties:
lovesRocks:
type: boolean

a payload like this:

{
"pet_type": "Cat",
"name": "misty"
}

will indicate that the Cat schema be used. Likewise this schema:

{
"pet_type": "cachorro",
"bark": "soft"
}

will map to Dog because of the definition in the mappings element.