Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotated enums and extended validation #4111

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion versions/3.1.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
handrews marked this conversation as resolved.
Show resolved Hide resolved
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.
handrews marked this conversation as resolved.
Show resolved Hide resolved

###### 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.
handrews marked this conversation as resolved.
Show resolved Hide resolved

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]].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the example here is a bit off. A readOnly field is essentially "set by the server" -- and that would apply to both the initial creation of a resource as well as a replace of the resource. So I don't think it's accurate to say that omitting the field would result in its deletion.

I think a better argument for ignoring readOnly fields sent in a request body is to avoid requiring a client to remove these fields when updating a resource with a GET-followed-by-PUT sequence of operations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikekistler I'll update this tonight - I mostly agree with you but want to think on the right way to frame it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikekistler I've updated it and removed discussion of PUT semantics (even though I really, really, want to rant about PUT semantics... PUT is so misunderstood). I'm open to further tweaks but I think what I have shows a couple of closerly related use cases. Which feels a bit better than focusing on exactly one. I think it will encourage folks to think about the possibilities more. But I am definitely open to changing it further.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note on PUT: I never got around to consolidate my rants about PUT into a blog post on "How to use PUT without shooting yourself in the foot" that I can reference instead of writing a new rant - a blatant violation of the DRY principle 😎

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ralfhandl I, too, have a barely-started blog post on PUT that I should really finish...


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.
Expand All @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I like this! Great addition!


###### 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.

Expand Down Expand Up @@ -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
handrews marked this conversation as resolved.
Show resolved Hide resolved
title: Red, Green, Blue
description: Specify colors with the red, green, and blue additive color model
- const: cmyk
handrews marked this conversation as resolved.
Show resolved Hide resolved
title: Cyan, Magenta, Yellow, Black
description: Specify colors with the cyan, magenta, yellow, and black subtractive color model
```

###### Model with Example

```json
Expand Down