Skip to content

Commit 52bdba7

Browse files
handrewsjdesrosiers
andcommitted
Clarify discriminator + oneOf/anyOf/allOf usage (3.1.1)
This moves some guidance up to the fixed fields section where it is more obvious, and explicitly designates other configurations as having undefined behavior. It also creates subsections to organize the different topics, pulls key guidance out of the examples and up into those sections, and provides clarification on the ambiguity of names and URIs. Finally, it incorporates ideas from @jdesrosiers regarding the ambiguous `mapping` syntax submitted in a prior PR, but does so in a way that meets our compatibility requirements for patch releases. For the same compatibility reasons, the MUST wording for requiring the named discriminator property in the schema was (regrettably) weakened to a "SHOULD but otherwise undefined", as we have done for other problematic ambiguities. Co-authored-by: Jason Desrosiers <[email protected]>
1 parent d94d13f commit 52bdba7

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

versions/3.1.1.md

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ When parsing an OAD, JSON or YAML objects are parsed into specific Objects (such
191191

192192
If the same JSON/YAML object is parsed multiple times and the respective contexts require it to be parsed as _different_ Object types, the resulting behavior is _implementation defined_, and MAY be treated as an error if detected. An example would be referencing an empty Schema Object under `#/components/schemas` where a Path Item Object is expected, as an empty object is valid for both types. For maximum interoperability, it is RECOMMENDED that OpenAPI Description authors avoid such scenarios.
193193

194+
#### <a name="resolvingImplicitConnections"></a>Resolving Implicit Connections
195+
196+
***TODO: In another PR***
197+
194198
### <a name="dataTypes"></a>Data Types
195199

196200
Data types in the OAS are based on the types supported by the [JSON Schema Specification Draft 2020-12](https://tools.ietf.org/html/draft-bhutton-json-schema-00#section-4.2.1).
@@ -2922,24 +2926,38 @@ components:
29222926
29232927
#### <a name="discriminatorObject"></a>Discriminator Object
29242928
2925-
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. It can be used to aid in serialization, deserialization, and validation.
2926-
2927-
`discriminator` uses a schema's "name" to automatically map a property value to
2928-
a schema. The schema's "name" is the property name used when declaring the
2929-
schema as a component in an OpenAPI document. For example, the name of the
2930-
schema at `#/components/schemas/Cat` is "Cat". Therefore, when using
2931-
`discriminator`, _inline_ schemas will not be considered because they don't have
2932-
a "name".
2929+
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.
2930+
This hint can be used to aid in serialization, deserialization, and validation.
2931+
The Discriminator Object does this by implicitly or explicitly associating the possible values of a named property with alternative schemas.
29332932
29342933
##### Fixed Fields
29352934
Field Name | Type | Description
29362935
---|:---:|---
2937-
<a name="propertyName"></a>propertyName | `string` | **REQUIRED**. The name of the property in the payload that will hold the discriminator value. This property MUST be required in the payload schema.
2938-
<a name="discriminatorMapping"></a> mapping | Map[`string`, `string`] | An object to hold mappings between payload values and schema names or references.
2936+
<a name="propertyName"></a>propertyName | `string` | **REQUIRED**. The name of the property in the payload that will hold the discriminator value. This property SHOULD be required in the payload schema, as the behavior when the property is absent is undefined.
2937+
<a name="discriminatorMapping"></a> mapping | Map[`string`, `string`] | An object to hold mappings between payload values and schema names or URI references.
29392938

29402939
This object MAY be extended with [Specification Extensions](#specificationExtensions).
29412940

2942-
The discriminator object is legal only when using one of the composite keywords `oneOf`, `anyOf`, `allOf`. Note that because the discriminating property's value is used as a component name and/or as the key in the `mapping` object, the behavior of any value that is not a string is undefined.
2941+
##### Conditions for Using the Discriminator Object
2942+
The Discriminator Object is legal only when using one of the composite keywords `oneOf`, `anyOf`, `allOf`.
2943+
In both the `oneOf` and `anyOf` use cases, where those keywords are adjacent to `discriminator`, all possible schemas MUST be listed explicitly.
2944+
To avoid redundancy, the discriminator MAY be added to a parent schema definition, and all schemas building on the parent schema via an `allOf` construct may be used as an alternate schema.
2945+
2946+
The behavior of any configuration of `oneOf`, `anyOf`, `allOf` and `discriminator` that is not described above is undefined.
2947+
2948+
##### Options for Mapping Values to Schemas
2949+
The value of the property named in `propertyName` is used as the name of the associated schema under the [Components Object](#componentsObject), _unless_ a `mapping` is present for that value.
2950+
The `mapping` entry maps a specific property value to either a different schema component name, or to a schema identified by a URI.
2951+
When using implicit or explicit schema component names, inline `oneOf` or `anyOf` subschemas are not considered.
2952+
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.
2953+
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"`).
2954+
2955+
Mapping keys MUST be string values, but tooling MAY convert response values to strings for comparison.
2956+
However, the exact nature of such conversions are implementation-defined.
2957+
2958+
##### <a name="discriminatorExamples"></a>Examples
2959+
2960+
For these examples, assume all schemas are in the entry OpenAPI document; for handling of `discriminator` in referenced documents see [Resolving Implicit Connections](#resolvingImplicitConnections).
29432961

29442962
In OAS 3.x, a response payload MAY be described to be exactly one of any number of types:
29452963

@@ -2990,13 +3008,11 @@ MyResponseType:
29903008
monster: https://gigantic-server.com/schemas/Monster/schema.json
29913009
```
29923010

2993-
Here the discriminator _value_ of `dog` will map to the schema `#/components/schemas/Dog`, rather than the default (implicit) `#/components/schemas/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.
3011+
Here the discriminator property _value_ of `dog` will map to the schema `#/components/schemas/Dog`, rather than the default (implicit) value of `#/components/schemas/dog`. If the discriminator property _value_ does not match an implicit or explicit mapping, no schema can be determined and validation SHOULD fail.
29943012

29953013
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.
29963014

2997-
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.
2998-
2999-
For example:
3015+
This example shows the `allOf` usage, which avoids needing to reference all child schemas in the parent:
30003016

30013017
```yaml
30023018
components:

0 commit comments

Comments
 (0)