From 1bd77b40955c15ae7a21fb685c119cce04ff12ff Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Tue, 24 Sep 2024 06:50:31 -0700 Subject: [PATCH 1/5] Annotated enums and extended validation This tidies up the increasingly long Schema Object section and adds explanations of what I've been calling "extended validation", including validating `readOnly` and `writeOnly`, and also using a `oneOf` or `anyOf` with `const` plus annotations for enumerated types with additional information. There are many OAS issues/discussions where we have recommended these techniques, so it makes sense to include them in 3.1.1 where draft 2020-12's formal collection of annotations enables tools to build support for them. --- versions/3.1.1.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/versions/3.1.1.md b/versions/3.1.1.md index bcd08b8fde..40ccf8e22c 100644 --- a/versions/3.1.1.md +++ b/versions/3.1.1.md @@ -2758,6 +2758,29 @@ JSON Schema implementations MAY choose to treat keywords defined by the OpenAPI This object MAY be extended with [Specification Extensions](#specification-extensions), though as noted, additional properties MAY omit the `x-` prefix within this object. +##### Extended Validation with Annotations + +JSON Schema draft 2020-12 supports [collecting annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-7.7.1), including [treating unrecognized keywords as annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-6.5). +OAS implementations MAY use such annotations, including [extensions](https://spec.openapis.org/registry/extension/) not recognized as part of a declared JSON Schema vocabulary, as the basis for further validation. +Note that JSON Schema draft 2020-12 does not require an `x-` prefix for extensions. + +###### Non-validating constraint keywords + +The [`format` keyword (when using default format-annotation vocabulary)](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-7.2.1) and the [`contentMediaType`, `contentEncoding`, and `contentSchema` keywords](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-8.2) define constraints on the data, but are treated as annotations instead of being validated directly. +Extended validation is one way that these constraints MAY be enforced. + +###### Validating `readOnly` and `writeOnly` + +The `readOnly` and `writeOnly` keywords are annotations, as JSON Schema is not aware of how the data it is validating is being used. +Validation of these keywords MAY be done by checking the annotation, the read or write direction, and (if relevant) the current value of the field. +[JSON Schema Validation draft 2020-12 §9.4](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-9.4) defines the expectations of these keywords, including that resource (described as the "owning authority") MAY either ignore a `readOnly` field or treat it as an error. + +An example of where ignoring a "written" `readOnly` field might be appropriate is a PUT request where the field is included but the value has not been changed, since the alternative of leaving out the field would result in the field's deletion per [[RFC7231]]. + +Note that the behavior of `readOnly` in particular differs from that specified by version 3.0 of this specification. + +##### Data Modeling Techniques + ###### Composition and Inheritance (Polymorphism) The OpenAPI Specification allows combining and extending model definitions using the `allOf` keyword of JSON Schema, in effect offering model composition. @@ -2781,12 +2804,18 @@ Implementations MAY support defining generic or template data structures using J An example is included in the "Schema Object Examples" section below, and further information can be found on the Learn OpenAPI site's ["Dynamic References"](https://learn.openapis.org/referencing/dynamic.html) page. +###### Annotated Enumerations + +The Schema Object's `enum` keyword does not allow associating descriptions or other information with individual values. + +Implementations MAY support recognizing a `oneOf` or `anyOf` where each subschema in the keyword's array consists of a `const` keyword and annotations such as `title` or `description` as an enumerated type with additional information. The exact behavior of this pattern beyond what is required by JSON Schema is implementation-defined. + ###### XML Modeling The [xml](#schema-xml) field allows extra definitions when translating the JSON definition to XML. The [XML Object](#xml-object) contains additional information about the available options. -###### Specifying Schema Dialects +##### Specifying Schema Dialects It is important for tooling to be able to determine which dialect or meta-schema any given resource wishes to be processed with: JSON Schema Core, JSON Schema Validation, OpenAPI Schema dialect, or some custom meta-schema. @@ -2886,6 +2915,32 @@ additionalProperties: $ref: '#/components/schemas/ComplexModel' ``` +###### Model with Annotated Enumeration + +```json +{ + "oneOf": [{ + "const": "RGB", + "title": "Red, Green, Blue", + "description": "Specify colors with the red, green, and blue additive color model" + }, { + "const": "CMYK", + "title": "Cyan, Magenta, Yellow, Black", + "description": "Specify colors with the cyan, magenta, yellow, and black subtractive color model" + }] +} +``` + +```yaml + oneOf: + - const: rgb + title: Red, Green, Blue + description: Specify colors with the red, green, and blue additive color model + - const: cmyk + title: Cyan, Magenta, Yellow, Black + description: Specify colors with the cyan, magenta, yellow, and black subtractive color model +``` + ###### Model with Example ```json From fb2795364fcf144c45db700b70b8ab8c618bd00d Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Tue, 24 Sep 2024 07:49:06 -0700 Subject: [PATCH 2/5] Fix capitalizations Co-authored-by: Ralf Handl --- versions/3.1.1.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/versions/3.1.1.md b/versions/3.1.1.md index 40ccf8e22c..54a2f32199 100644 --- a/versions/3.1.1.md +++ b/versions/3.1.1.md @@ -2760,9 +2760,9 @@ This object MAY be extended with [Specification Extensions](#specification-exten ##### Extended Validation with Annotations -JSON Schema draft 2020-12 supports [collecting annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-7.7.1), including [treating unrecognized keywords as annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-6.5). +JSON Schema Draft 2020-12 supports [collecting annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-7.7.1), including [treating unrecognized keywords as annotations](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-6.5). OAS implementations MAY use such annotations, including [extensions](https://spec.openapis.org/registry/extension/) not recognized as part of a declared JSON Schema vocabulary, as the basis for further validation. -Note that JSON Schema draft 2020-12 does not require an `x-` prefix for extensions. +Note that JSON Schema Draft 2020-12 does not require an `x-` prefix for extensions. ###### Non-validating constraint keywords @@ -2773,7 +2773,7 @@ Extended validation is one way that these constraints MAY be enforced. The `readOnly` and `writeOnly` keywords are annotations, as JSON Schema is not aware of how the data it is validating is being used. Validation of these keywords MAY be done by checking the annotation, the read or write direction, and (if relevant) the current value of the field. -[JSON Schema Validation draft 2020-12 §9.4](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-9.4) defines the expectations of these keywords, including that resource (described as the "owning authority") MAY either ignore a `readOnly` field or treat it as an error. +[JSON Schema Validation Draft 2020-12 §9.4](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-9.4) defines the expectations of these keywords, including that a resource (described as the "owning authority") MAY either ignore a `readOnly` field or treat it as an error. An example of where ignoring a "written" `readOnly` field might be appropriate is a PUT request where the field is included but the value has not been changed, since the alternative of leaving out the field would result in the field's deletion per [[RFC7231]]. @@ -2933,10 +2933,10 @@ additionalProperties: ```yaml oneOf: - - const: rgb + - const: RGB title: Red, Green, Blue description: Specify colors with the red, green, and blue additive color model - - const: cmyk + - const: CMYK title: Cyan, Magenta, Yellow, Black description: Specify colors with the cyan, magenta, yellow, and black subtractive color model ``` From 9e1e71d74ee2ba8d654cd17fc884f19f74bbf0fa Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Tue, 24 Sep 2024 17:57:35 +0200 Subject: [PATCH 3/5] format-markdown --- versions/3.1.1.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/versions/3.1.1.md b/versions/3.1.1.md index 54a2f32199..7ba6d54dbb 100644 --- a/versions/3.1.1.md +++ b/versions/3.1.1.md @@ -2775,7 +2775,7 @@ The `readOnly` and `writeOnly` keywords are annotations, as JSON Schema is not a Validation of these keywords MAY be done by checking the annotation, the read or write direction, and (if relevant) the current value of the field. [JSON Schema Validation Draft 2020-12 §9.4](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-9.4) defines the expectations of these keywords, including that a resource (described as the "owning authority") MAY either ignore a `readOnly` field or treat it as an error. -An example of where ignoring a "written" `readOnly` field might be appropriate is a PUT request where the field is included but the value has not been changed, since the alternative of leaving out the field would result in the field's deletion per [[RFC7231]]. +An example of where ignoring a "written" `readOnly` field might be appropriate is a PUT request where the field is included but the value has not been changed, since the alternative of leaving out the field would result in the field's deletion per [[RFC7231]]. Note that the behavior of `readOnly` in particular differs from that specified by version 3.0 of this specification. @@ -2808,7 +2808,7 @@ An example is included in the "Schema Object Examples" section below, and furthe The Schema Object's `enum` keyword does not allow associating descriptions or other information with individual values. -Implementations MAY support recognizing a `oneOf` or `anyOf` where each subschema in the keyword's array consists of a `const` keyword and annotations such as `title` or `description` as an enumerated type with additional information. The exact behavior of this pattern beyond what is required by JSON Schema is implementation-defined. +Implementations MAY support recognizing a `oneOf` or `anyOf` where each subschema in the keyword's array consists of a `const` keyword and annotations such as `title` or `description` as an enumerated type with additional information. The exact behavior of this pattern beyond what is required by JSON Schema is implementation-defined. ###### XML Modeling @@ -2919,20 +2919,23 @@ additionalProperties: ```json { - "oneOf": [{ - "const": "RGB", - "title": "Red, Green, Blue", - "description": "Specify colors with the red, green, and blue additive color model" - }, { - "const": "CMYK", - "title": "Cyan, Magenta, Yellow, Black", - "description": "Specify colors with the cyan, magenta, yellow, and black subtractive color model" - }] + "oneOf": [ + { + "const": "RGB", + "title": "Red, Green, Blue", + "description": "Specify colors with the red, green, and blue additive color model" + }, + { + "const": "CMYK", + "title": "Cyan, Magenta, Yellow, Black", + "description": "Specify colors with the cyan, magenta, yellow, and black subtractive color model" + } + ] } ``` ```yaml - oneOf: +oneOf: - const: RGB title: Red, Green, Blue description: Specify colors with the red, green, and blue additive color model @@ -4520,7 +4523,7 @@ This keeps it outside of the processes governed by this specification. ## Appendix F: Resolving Security Requirements in a Referenced Document -This appendix shows how to retrieve an HTTP-accessible multi-document OpenAPI Description (OAD) and resolve a [Security Requirement Object](#security-requirement-object) in the referenced (non-entry) document. See [Resolving Implicit Connections](#resolving-implicit-connections) for more information. +This appendix shows how to retrieve an HTTP-accessible multi-document OpenAPI Description (OAD) and resolve a [Security Requirement Object](#security-requirement-object) in the referenced (non-entry) document. See [Resolving Implicit Connections](#resolving-implicit-connections) for more information. First, the [entry document](#openapi-description-structure) is where parsing begins. It defines the `MySecurity` security scheme to be JWT-based, and it defines a Path Item as a reference to a component in another document: @@ -4565,7 +4568,7 @@ paths: $ref: 'other#/components/pathItems/Foo' ``` -This entry document references another document, `other`, without using a file extension. This gives the client the flexibility to choose an acceptable format on a resource-by-resource basis, assuming both representations are available: +This entry document references another document, `other`, without using a file extension. This gives the client the flexibility to choose an acceptable format on a resource-by-resource basis, assuming both representations are available: ```HTTP GET /api/description/other HTTP/1.1 From dfd317850f9c2b60c4b287a93e4f375fbf315f95 Mon Sep 17 00:00:00 2001 From: Ralf Handl Date: Tue, 24 Sep 2024 18:02:23 +0200 Subject: [PATCH 4/5] chmod +x --- scripts/format-markdown.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/format-markdown.sh diff --git a/scripts/format-markdown.sh b/scripts/format-markdown.sh old mode 100644 new mode 100755 From d269e393b8c8f4860d23d40ee701ef27b7d35bed Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Tue, 24 Sep 2024 20:39:15 -0700 Subject: [PATCH 5/5] Better example of ignoring a readOnly constraint --- versions/3.1.1.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/versions/3.1.1.md b/versions/3.1.1.md index 7ba6d54dbb..e7d8ada90e 100644 --- a/versions/3.1.1.md +++ b/versions/3.1.1.md @@ -2775,7 +2775,9 @@ The `readOnly` and `writeOnly` keywords are annotations, as JSON Schema is not a Validation of these keywords MAY be done by checking the annotation, the read or write direction, and (if relevant) the current value of the field. [JSON Schema Validation Draft 2020-12 §9.4](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-9.4) defines the expectations of these keywords, including that a resource (described as the "owning authority") MAY either ignore a `readOnly` field or treat it as an error. -An example of where ignoring a "written" `readOnly` field might be appropriate is a PUT request where the field is included but the value has not been changed, since the alternative of leaving out the field would result in the field's deletion per [[RFC7231]]. +Fields that are both required and read-only are an example of when it is beneficial to ignore a `readOnly: true` constraint in a PUT, particularly if the value has not been changed. +This allows correctly requiring the field on a GET and still using the same representation and schema with PUT. +Even when read-only fields are not required, stripping them is burdensome for clients, particularly when the JSON data is complex or deeply nested. Note that the behavior of `readOnly` in particular differs from that specified by version 3.0 of this specification.