From 726929ffc91613fa01a764f80c8551fd95f2845d Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Sun, 19 May 2024 11:42:51 -0700 Subject: [PATCH 1/2] Further clarify discriminator usage (3.0.4) This backports changes made to the Discriminator Object in 3.1.1 and merges them with the changes made on this branch. Note that the previouc changes incorporated reworked ideas from @jdesrosiers regarding the ambiguous `mapping` syntax submitted in the 3.1.1 changes but not accepted at that time due to compatibility concerns. This commit merges in the parts of that 3.1.1 change that were accepted. 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 --- versions/3.0.4.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/versions/3.0.4.md b/versions/3.0.4.md index 12b2375a79..d363d7d3c9 100644 --- a/versions/3.0.4.md +++ b/versions/3.0.4.md @@ -163,6 +163,10 @@ When parsing an OAD, JSON or YAML objects are parsed into specific Objects (such 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. +#### Resolving Implicit Connections + +***TODO: In another PR*** + ### Data Types Primitive data types in the OAS are based on the types supported by the [JSON Schema Specification Wright Draft 00](https://tools.ietf.org/html/draft-wright-json-schema-00#section-4.2). @@ -2747,12 +2751,14 @@ components: #### Discriminator Object -When request bodies or response payloads may be one of a number of different schemas, a Discriminator Object can be used to aid in serialization, deserialization, and validation by implicitly or explicitly associating the possible values of a named property with alternative schemas. +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. +This hint can be used to aid in serialization, deserialization, and validation. +The Discriminator Object does this by implicitly or explicitly associating the possible values of a named property with alternative schemas. ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -propertyName | `string` | **REQUIRED**. The name of the property in the payload that will hold the discriminator value. +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. mapping | Map[`string`, `string`] | An object to hold mappings between payload values and schema names or URI references. ##### Conditions for Using the Discriminator Object @@ -2776,6 +2782,8 @@ However, the exact nature of such conversions are implementation-defined. ##### Examples +For these examples, assume all schemas are in the entry OpenAPI document; for handling of `discriminator` in referenced documents see [Resolving Implicit Connections](#resolvingImplicitConnections). + In OAS 3.0, a response payload MAY be described to be exactly one of any number of types: ```yaml @@ -2826,7 +2834,7 @@ MyResponseType: 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. +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. When used in conjunction with the `anyOf` construct, the use of the discriminator can avoid ambiguity where multiple schemas may satisfy a single payload. From 1308aa8ff45bde043b243a9dacdf64668577a9c5 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Fri, 31 May 2024 13:57:02 -0700 Subject: [PATCH 2/2] Use "discriminating value" consistently I found the "discriminator value" language confusing, because `discriminator` is the field name, and in most cases the value of a field is the value in the OpenAPI Description. Reviewers did not like "discriminator property value", but "discriminating value" makes it clear that this is about the value that actually causes schema selection, and not about the value of the discriminator keyword. Also removed placeholder in favor of just having the headings, as has been done in several other PRs that overlap with new section PRs for internal linking. --- versions/3.0.4.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/versions/3.0.4.md b/versions/3.0.4.md index d363d7d3c9..c19ef234ea 100644 --- a/versions/3.0.4.md +++ b/versions/3.0.4.md @@ -165,8 +165,6 @@ If the same JSON/YAML object is parsed multiple times and the respective context #### Resolving Implicit Connections -***TODO: In another PR*** - ### Data Types Primitive data types in the OAS are based on the types supported by the [JSON Schema Specification Wright Draft 00](https://tools.ietf.org/html/draft-wright-json-schema-00#section-4.2). @@ -2648,7 +2646,7 @@ components: ] }, "Cat": { - "description": "A representation of a cat. Note that `Cat` will be used as the discriminator value.", + "description": "A representation of a cat. Note that `Cat` will be used as the discriminating value.", "allOf": [ { "$ref": "#/components/schemas/Pet" @@ -2675,7 +2673,7 @@ components: ] }, "Dog": { - "description": "A representation of a dog. Note that `Dog` will be used as the discriminator value.", + "description": "A representation of a dog. Note that `Dog` will be used as the discriminating value.", "allOf": [ { "$ref": "#/components/schemas/Pet" @@ -2717,7 +2715,7 @@ components: required: - name - petType - Cat: # "Cat" will be used as the discriminator value + Cat: # "Cat" will be used as the discriminating value description: A representation of a cat allOf: - $ref: '#/components/schemas/Pet' @@ -2733,7 +2731,7 @@ components: - aggressive required: - huntingSkill - Dog: # "Dog" will be used as the discriminator value + Dog: # "Dog" will be used as the discriminating value description: A representation of a dog allOf: - $ref: '#/components/schemas/Pet' @@ -2758,7 +2756,7 @@ The Discriminator Object does this by implicitly or explicitly associating the p ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -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. +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. mapping | Map[`string`, `string`] | An object to hold mappings between payload values and schema names or URI references. ##### Conditions for Using the Discriminator Object @@ -2834,7 +2832,7 @@ MyResponseType: monster: https://gigantic-server.com/schemas/Monster/schema.json ``` -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. +Here the discriminating value of `dog` will map to the schema `#/components/schemas/Dog`, rather than the default (implicit) value of `#/components/schemas/dog`. If the discriminating value does not match an implicit or explicit mapping, no schema can be determined and validation SHOULD fail. When used in conjunction with the `anyOf` construct, the use of the discriminator can avoid ambiguity where multiple schemas may satisfy a single payload.