You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -2832,7 +2832,7 @@ JSON Schema implementations MAY choose to treat keywords defined by the OpenAPI
2832
2832
2833
2833
| Field Name | Type | Description |
2834
2834
| ---- | :----: | ---- |
2835
-
| <a name="schema-discriminator"></a>discriminator | [Discriminator Object](#discriminator-object) | Adds support for polymorphism. The discriminator is used to determine which of a set of schemas a payload is expected to satisfy. See [Composition and Inheritance](#composition-and-inheritance-polymorphism) for more details. |
2835
+
| <a name="schema-discriminator"></a>discriminator | [Discriminator Object](#discriminator-object) | The discriminator provides a "hint" for which of a set of schemas a payload is expected to satisfy. See [Composition and Inheritance](#composition-and-inheritance-polymorphism) for more details. |
2836
2836
| <a name="schema-xml"></a>xml | [XML Object](#xml-object) | This MAY be used only on property schemas. It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property. |
2837
2837
| <a name="schema-external-docs"></a>externalDocs | [External Documentation Object](#external-documentation-object) | Additional external documentation for this schema. |
2838
2838
| <a name="schema-example"></a>example | Any | A free-form field to include an example of an instance for this schema. To represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary.<br><br>**Deprecated:** The `example` field has been deprecated in favor of the JSON Schema `examples` keyword. Use of `example` is discouraged, and later versions of this specification may remove it. |
@@ -2870,10 +2870,16 @@ The OpenAPI Specification allows combining and extending model definitions using
2870
2870
`allOf`takes an array of object definitions that are validated _independently_ but together compose a single object.
2871
2871
2872
2872
While composition offers model extensibility, it does not imply a hierarchy between the models.
2873
-
To support polymorphism, the OpenAPI Specification adds the [`discriminator`](#schema-discriminator) field.
2874
-
When used, the `discriminator` indicates the name of the property that hints which schema definition is expected to validate the structure of the model.
2875
-
As such, the `discriminator` field MUST be a required field.
2876
-
There are two ways to define the value of a discriminator for an inheriting instance.
2873
+
2874
+
JSON Schema also provides the `anyOf` and `oneOf` keywords, which allow defining multiple schemas where at least one or exactly one of them must be valid, respectively.
2875
+
As is the case with `allOf`, the schemas are validated _independently_.
2876
+
These keywords can be used to describe polymorphism, where a single field can accept multiple types of values.
2877
+
2878
+
The OpenAPI specification extends the JSON Schema support for polymorphism by adding the [`discriminator`](#schema-discriminator) field whose value is a [Discriminator Object](#discriminator-object).
2879
+
When used, the Discriminator Object indicates the name of the property that hints which schema of an `anyOf` or `oneOf` is expected to validate the structure of the model.
2880
+
The discriminating property MAY be defined as required or optional, but when defined as an optional property the Discriminator Object MUST include a `defaultMapping` field that specifies which schema of the `anyOf` or `oneOf`, or which schema that references the current schema in an `allOf`, is expected to validate the structure of the model when the discriminating property is not present.
2881
+
2882
+
There are two ways to define the value of a discriminating property for an inheriting instance.
2877
2883
2878
2884
* Use the schema name.
2879
2885
* [Override the schema name](#discriminator-mapping) by overriding the property with a new value. If a new value exists, this takes precedence over the schema name.
@@ -3135,71 +3141,114 @@ components:
3135
3141
3136
3142
###### Models with Polymorphism Support
3137
3143
3138
-
```json
3139
-
{
3140
-
"components": {
3141
-
"schemas": {
3142
-
"Pet": {
3143
-
"type": "object",
3144
-
"discriminator": {
3145
-
"propertyName": "petType"
3146
-
},
3147
-
"properties": {
3148
-
"name": {
3149
-
"type": "string"
3150
-
},
3151
-
"petType": {
3152
-
"type": "string"
3153
-
}
3154
-
},
3155
-
"required": ["name", "petType"]
3156
-
},
3157
-
"Cat": {
3158
-
"description": "A representation of a cat. Note that `Cat` will be used as the discriminating value.",
"description": "A representation of a dog. Note that `Dog` will be used as the discriminating value.",
3179
-
"allOf": [
3180
-
{
3181
-
"$ref": "#/components/schemas/Pet"
3182
-
},
3183
-
{
3184
-
"type": "object",
3185
-
"properties": {
3186
-
"packSize": {
3187
-
"type": "integer",
3188
-
"format": "int32",
3189
-
"description": "the size of the pack the dog is from",
3190
-
"default": 0,
3191
-
"minimum": 0
3192
-
}
3193
-
},
3194
-
"required": ["packSize"]
3195
-
}
3196
-
]
3197
-
}
3198
-
}
3199
-
}
3200
-
}
3144
+
The following example describes a `Pet` model that can represent either a cat or a dog, as distinguished by the `petType` property. Each type of pet has other properties beyond those of the base `Pet` model. An instance without a `petType` property, or with a `petType` property that does not match either `cat` or `dog`, is invalid.
3145
+
3146
+
```yaml
3147
+
components:
3148
+
schemas:
3149
+
Pet:
3150
+
type: object
3151
+
properties:
3152
+
name:
3153
+
type: string
3154
+
required:
3155
+
- name
3156
+
- petType
3157
+
oneOf:
3158
+
- $ref: '#/components/schemas/Cat'
3159
+
- $ref: '#/components/schemas/Dog'
3160
+
Cat:
3161
+
description: A pet cat
3162
+
type: object
3163
+
properties:
3164
+
petType:
3165
+
const: 'cat'
3166
+
huntingSkill:
3167
+
type: string
3168
+
description: The measured skill for hunting
3169
+
enum:
3170
+
- clueless
3171
+
- lazy
3172
+
- adventurous
3173
+
- aggressive
3174
+
required:
3175
+
- huntingSkill
3176
+
Dog:
3177
+
description: A pet dog
3178
+
type: object
3179
+
properties:
3180
+
petType:
3181
+
const: 'dog'
3182
+
packSize:
3183
+
type: integer
3184
+
format: int32
3185
+
description: the size of the pack the dog is from
3186
+
default: 0
3187
+
minimum: 0
3188
+
required:
3189
+
- packSize
3201
3190
```
3202
3191
3192
+
###### Models with Polymorphism Support and a Discriminator Object
3193
+
3194
+
The following example extends the example of the previous section by adding a [Discriminator Object](#discriminator-object) to the `Pet` schema. Note that the Discriminator Object is only a hint to the consumer of the API and does not change the validation outcome of the schema.
3195
+
3196
+
```yaml
3197
+
components:
3198
+
schemas:
3199
+
Pet:
3200
+
type: object
3201
+
discriminator:
3202
+
propertyName: petType
3203
+
mapping:
3204
+
cat: '#/components/schemas/Cat'
3205
+
dog: '#/components/schemas/Dog'
3206
+
properties:
3207
+
name:
3208
+
type: string
3209
+
required:
3210
+
- name
3211
+
- petType
3212
+
oneOf:
3213
+
- $ref: '#/components/schemas/Cat'
3214
+
- $ref: '#/components/schemas/Dog'
3215
+
Cat:
3216
+
description: A pet cat
3217
+
type: object
3218
+
properties:
3219
+
petType:
3220
+
const: 'cat'
3221
+
huntingSkill:
3222
+
type: string
3223
+
description: The measured skill for hunting
3224
+
enum:
3225
+
- clueless
3226
+
- lazy
3227
+
- adventurous
3228
+
- aggressive
3229
+
required:
3230
+
- huntingSkill
3231
+
Dog:
3232
+
description: A pet dog
3233
+
type: object
3234
+
properties:
3235
+
petType:
3236
+
const: 'dog'
3237
+
packSize:
3238
+
type: integer
3239
+
format: int32
3240
+
description: the size of the pack the dog is from
3241
+
default: 0
3242
+
minimum: 0
3243
+
required:
3244
+
- petType
3245
+
- packSize
3246
+
```
3247
+
3248
+
###### Models with Polymorphism Support using allOf and a Discriminator Object
3249
+
3250
+
It is also possible to describe polymorphic models using `allOf`. The following example uses `allOf` with a [Discriminator Object](#discriminator-object) to describe a polymorphic `Pet` model.
3251
+
3203
3252
```yaml
3204
3253
components:
3205
3254
schemas:
@@ -3362,7 +3411,9 @@ components:
3362
3411
3363
3412
#### Discriminator Object
3364
3413
3365
-
When request bodies or response payloads may be one of a number of different schemas, a Discriminator Object gives a hint about the expected schema of the document.
3414
+
When request bodies or response payloads may be one of a number of different schemas, these should use the JSON Schema `anyOf` or `oneOf` keywords to describe the possible schemas (see [Composition and Inheritance](#composition-and-inheritance-polymorphism)).
3415
+
3416
+
A polymorphic schema MAY include a Discriminator Object, which defines the name of the property that may be used as a hint for which schema of the `anyOf` or `oneOf`, or which schema that references the current schema in an `allOf`, is expected to validate the structure of the model.
3366
3417
This hint can be used to aid in serialization, deserialization, and validation.
3367
3418
The Discriminator Object does this by implicitly or explicitly associating the possible values of a named property with alternative schemas.
3368
3419
@@ -3372,8 +3423,9 @@ Note that `discriminator` MUST NOT change the validation outcome of the schema.
3372
3423
3373
3424
| Field Name | Type | Description |
3374
3425
| ---- | :----: | ---- |
3375
-
| <a name="property-name"></a>propertyName | `string` | **REQUIRED**. The name of the property in the payload that will hold the discriminating value. This property SHOULD be required in the payload schema, as the behavior when the property is absent is undefined. |
3426
+
| <a name="property-name"></a>propertyName | `string` | **REQUIRED**. The name of the discriminating property in the payload that will hold the discriminating value. The discriminating property MAY be defined as required or optional, but when defined as optional the Discriminator Object MUST include a `defaultMapping` field that specifies which schema is expected to validate the structure of the model when the discriminating property is not present. |
3376
3427
| <a name="discriminator-mapping"></a> mapping | Map[`string`, `string`] | An object to hold mappings between payload values and schema names or URI references. |
3428
+
| <a name="default"></a> defaultMapping | `string` | The schema name or URI reference to a schema that is expected to validate the structure of the model when the discriminating property is not present in the payload or contains a value for which there is no explicit or implicit mapping. |
3377
3429
3378
3430
This object MAY be extended with [Specification Extensions](#specification-extensions).
3379
3431
@@ -3395,12 +3447,33 @@ The behavior of any configuration of `oneOf`, `anyOf`, `allOf` and `discriminato
3395
3447
The value of the property named in `propertyName` is used as the name of the associated schema under the [Components Object](#components-object), _unless_ a `mapping` is present for that value.
3396
3448
The `mapping` entry maps a specific property value to either a different schema component name, or to a schema identified by a URI.
3397
3449
When using implicit or explicit schema component names, inline `oneOf` or `anyOf` subschemas are not considered.
3398
-
The behavior of a `mapping` value that is both a valid schema name and a valid relative URI reference is implementation-defined, but it is RECOMMENDED that it be treated as a schema name.
3450
+
The behavior of a `mapping` value or `defaultMapping` value that is both a valid schema name and a valid relative URI reference is implementation-defined, but it is RECOMMENDED that it be treated as a schema name.
3399
3451
To ensure that an ambiguous value (e.g. `"foo"`) is treated as a relative URI reference by all implementations, authors MUST prefix it with the `"."` path segment (e.g. `"./foo"`).
3400
3452
3401
3453
Mapping keys MUST be string values, but tooling MAY convert response values to strings for comparison.
3402
3454
However, the exact nature of such conversions are implementation-defined.
3403
3455
3456
+
##### Optional discriminating property
3457
+
3458
+
When the discriminating property is defined as optional, the [Discriminator Object](#discriminator-object) MUST include a `defaultMapping` field that specifies a schema that is expected to validate the structure of the model when the discriminating property is not present in the payload or contains a value for which there is no explicit or implicit mapping. This allows the schema to still be validated correctly even if the discriminating property is missing.
3459
+
3460
+
The primary use case for an optional discriminating property is to allow a schema to be extended with a discriminator without breaking existing clients that do not provide the discriminating property.
3461
+
3462
+
When the discriminating property is defined as optional, it is important that each subschema that defines a value for the discriminating property also define the property as required, since this is no longer enforced by the parent schema.
3463
+
3464
+
The `defaultMapping` schema is also expected to validate the structure of the model when the discriminating property is present but contains a value for which there is no explicit or implicit mapping. This is typically expressed in the `defaultMapping` schema by excluding any instances with mapped values of the discriminating property, e.g.
3465
+
3466
+
```yaml
3467
+
OtherPet:
3468
+
type: object
3469
+
properties:
3470
+
petType:
3471
+
not:
3472
+
enum: ['cat', 'dog']
3473
+
```
3474
+
3475
+
This prevents the `defaultMapping` schema from validating a payload that includes the discriminating property with a mapped discriminating value, which would cause a validation to fail when polymorphism is described using the `oneOf` JSON schema keyword.
3476
+
3404
3477
##### Examples
3405
3478
3406
3479
For these examples, assume all schemas are in the [entry document](#openapi-description-structure) of the OAD; for handling of `discriminator` in referenced documents see [Resolving Implicit Connections](#resolving-implicit-connections).
@@ -3415,7 +3488,7 @@ MyResponseType:
3415
3488
- $ref: '#/components/schemas/Lizard'
3416
3489
```
3417
3490
3418
-
which means the payload _MUST_, by validation, match exactly one of the schemas described by `Cat`, `Dog`, or `Lizard`. Deserialization of a `oneOf` can be a costly operation, as it requires determining which schema matches the payload and thus should be used in deserialization. This problem also exists for `anyOf` schemas. A `discriminator` MAY be used as a "hint" to improve the efficiency of selection of the matching schema. The `discriminator` field cannot change the validation result of the `oneOf`, it can only help make the deserialization more efficient and provide better error messaging. We can specify the exact field that tells us which schema is expected to match the instance:
3491
+
which means a valid payload has to match exactly one of the schemas described by `Cat`, `Dog`, or `Lizard`. Deserialization of a `oneOf` can be a costly operation, as it requires determining which schema matches the payload and thus should be used in deserialization. This problem also exists for `anyOf` schemas. A `discriminator` can be used as a "hint" to improve the efficiency of selection of the matching schema. The [Discriminator Object](#discriminator-object) cannot change the validation result of the `oneOf`, it can only help make the deserialization more efficient and provide better error messaging. We can specify the exact field that tells us which schema is expected to match the instance:
3419
3492
3420
3493
```yaml
3421
3494
MyResponseType:
@@ -3438,7 +3511,7 @@ The expectation now is that a property with name `petType` _MUST_ be present in
3438
3511
3439
3512
will indicate that the `Cat` schema is expected to match this payload.
3440
3513
3441
-
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:
3514
+
In scenarios where the value of the discriminating property does not match the schema name or implicit mapping is not possible, an optional `mapping` definition can be used:
3442
3515
3443
3516
```yaml
3444
3517
MyResponseType:
@@ -3458,6 +3531,30 @@ Here the discriminating value of `dog` will map to the schema `#/components/sche
3458
3531
3459
3532
When used in conjunction with the `anyOf` construct, the use of the discriminator can avoid ambiguity for serializers/deserializers where multiple schemas may satisfy a single payload.
3460
3533
3534
+
When the discriminating property is defined as optional, the Discriminator Object has to include a `defaultMapping` field that specifies a schema of the `anyOf` or `oneOf` is expected to validate the structure of the model when the discriminating property is not present in the payload. This allows the schema to still be validated correctly even if the discriminator property is missing.
3535
+
3536
+
For example:
3537
+
3538
+
```yaml
3539
+
MyResponseType:
3540
+
oneOf:
3541
+
- $ref: '#/components/schemas/Cat'
3542
+
- $ref: '#/components/schemas/Dog'
3543
+
- $ref: '#/components/schemas/Lizard'
3544
+
- $ref: '#/components/schemas/OtherPet'
3545
+
discriminator:
3546
+
propertyName: petType
3547
+
defaultMapping: OtherPet
3548
+
OtherPet:
3549
+
type: object
3550
+
properties:
3551
+
petType:
3552
+
not:
3553
+
enum: ['Cat', 'Dog', 'Lizard']
3554
+
```
3555
+
3556
+
In this example, if the `petType` property is not present in the payload, or if the value of `petType` is not "Cat", "Dog", or "Lizard", then the payload should validate against the `OtherPet` schema.
3557
+
3461
3558
This example shows the `allOf` usage, which avoids needing to reference all child schemas in the parent:
0 commit comments