Skip to content

Commit 2940af6

Browse files
authored
Merge pull request #4799 from handrews/ex-obj-3
v3.2 Add data vs serialized example fields (3rd try)
2 parents 08ee9d6 + f88dc0d commit 2940af6

File tree

7 files changed

+118
-17
lines changed

7 files changed

+118
-17
lines changed

src/oas.md

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,42 +2137,86 @@ transactionCallback:
21372137
#### Example Object
21382138

21392139
An object grouping an internal or external example value with basic `summary` and `description` metadata.
2140+
The examples can show either data suitable for schema validation, or serialized data as required by the containing [Media Type Object](#media-type-object), [Parameter Object](#parameter-object), or [Header Object](#header-object).
21402141
This object is typically used in fields named `examples` (plural), and is a [referenceable](#reference-object) alternative to older `example` (singular) fields that do not support referencing or metadata.
2141-
2142-
Examples allow demonstration of the usage of properties, parameters and objects within OpenAPI.
2142+
The various fields and types of examples are explained in more detail under [Working With Examples](#working-with-examples).
21432143

21442144
##### Fixed Fields
21452145

21462146
| Field Name | Type | Description |
21472147
| ---- | :----: | ---- |
21482148
| <a name="example-summary"></a>summary | `string` | Short description for the example. |
21492149
| <a name="example-description"></a>description | `string` | Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
2150-
| <a name="example-value"></a>value | Any | Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. |
2151-
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The `value` field and `externalValue` field are mutually exclusive. See the rules for resolving [Relative References](#relative-references-in-api-description-uris). |
2150+
| <a name="example-data-value"></a>dataValue | Any | An example of the data structure that MUST be valid according to the relevant [Schema Object](#schema-object). If this field is present, `value` MUST be absent. |
2151+
| <a name="example-serialized-value"></a>serializedValue | `string` | An example of the serialized form of the value, including encoding and escaping as described under [Validating Examples](#validating-examples). If `dataValue` is present, then this field SHOULD contain the serialization of the given data. Otherwise, it SHOULD be the valid serialization of a data value that itself MUST be valid as described for `dataValue`. This field SHOULD NOT be used if the serialization format is JSON, as the data form is easier to work with. If this field is present, `value`, and `externalValue` MUST be absent. |
2152+
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the serialized example in a separate document, allowing for values not easily or readably expressed as a Unicode string. If `dataValue` is present, then this field SHOULD identify a serialization of the given data. Otherwise, the value SHOULD be the valid serialization of a data value that itself MUST be valid as described for `dataValue`. If this field is present, `serializedValue`, and `value` MUST be absent. See also the rules for resolving [Relative References](#relative-references-in-api-description-uris). |
2153+
| <a name="example-value"></a>value | Any | Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally be represented in JSON or YAML, use a string value to contain the example, escaping where necessary.<br><br>**Deprecated for non-JSON serialization targets:** Use `dataValue` and/or `serializedValue`, which both have unambiguous syntax and semantics, instead. |
21522154

21532155
This object MAY be extended with [Specification Extensions](#specification-extensions).
21542156

21552157
In all cases, the example value SHOULD be compatible with the schema of its associated value.
21562158
Tooling implementations MAY choose to validate compatibility automatically, and reject the example value(s) if incompatible.
2159+
See [Validating Examples](#validating-examples) for the exact meaning of "compatible" for each field in this Object.
21572160

21582161
##### Working with Examples
21592162

21602163
Example Objects can be used in [Parameter Objects](#parameter-object), [Header Objects](#header-object), and [Media Type Objects](#media-type-object).
21612164
In all three Objects, this is done through the `examples` (plural) field.
21622165
However, there are several other ways to provide examples: The `example` (singular) field that is mutually exclusive with `examples` in all three Objects, and two keywords (the deprecated singular `example` and the current plural `examples`, which takes an array of examples) in the [Schema Object](#schema-object) that appears in the `schema` field of all three Objects.
2166+
We will refer to the singular `example` field in the Parameter, Header, or Media Type Object, which has the same behavior as a single Example Object with only the `value` field, as the "shorthand `example`" field.
21632167
Each of these fields has slightly different considerations.
21642168

2165-
The Schema Object's fields are used to show example values without regard to how they might be formatted as parameters or within media type representations.
2166-
The `examples` array is part of JSON Schema and is the preferred way to include examples in the Schema Object, while `example` is retained purely for compatibility with older versions of the OpenAPI Specification.
2169+
###### JSON-Compatible and `value`-Safe Examples
2170+
2171+
The `value` and the shorthand `example` field are intended to have the same _semantics_ as `serializedValue` (or `externalValue`), while allowing a more convenient _syntax_ when there is no difference between a JSON (or [JSON-compatible YAML](#format)) representation and the final serialized form.
2172+
When using this syntax for `application/json` or any `+json` media type, these fields effectively behave like `dataValue`, as the serialization is trivial, and they are safe to use.
2173+
2174+
For data that consists of a single string, and a serialization target such as `text/plain` where the string is guaranteed to be serialized without any further escaping, these fields are also safe to use.
2175+
2176+
For other serialization targets, the ambiguity of the phrase "naturally be represented in JSON or YAML," as well as past errors in the parameter style examples table, have resulted in inconsistencies in the support and usage of these fields.
2177+
In practice, this has resulted in the `value` and shorthand `example` fields having implementation-defined behavior for non-JSON targets; OAD authors SHOULD use other fields to ensure interoperability.
2178+
2179+
###### Choosing Which Field(s) to Use
2180+
2181+
Keeping in mind the caveats from the previous section, and that the shorthand `example` can be used in place of `value` if there is only one Example Object involved, use the following guidelines to determine which field to use.
2182+
2183+
To show an example as it would be validated by a Schema Object:
2184+
2185+
* Use the Schema Object's `examples` array (from JSON Schema draft 2020-12) if the intent is to keep the example with the validating schema.
2186+
* Use the Schema Object's `example` (singular) only if compatibility with OAS v3.0 or earlier is required.
2187+
* Use the Example Object's `dataValue` field if the intent is to associate the example with an example of its serialization, or if it is desirable to maintain it separately from the schema.
2188+
* Use the Example Object's `value` field only if compatibility with OAS v3.1 or earlier is needed and the value can be "naturally represented in JSON or YAML" without any changes (such as percent-encoding) between the validation-ready value and the serialized representation.
2189+
2190+
To show an example as it would be serialized in order to construct an HTTP/1.1 message:
21672191

2168-
The mutually exclusive fields in the Parameter, Header, or Media Type Objects are used to show example values which SHOULD both match the schema and be formatted as they would appear as a serialized parameter, serialized header, or within a media type representation.
2169-
The exact serialization and encoding is determined by various fields in the Parameter Object, Header Object, or in the Media Type Object's [Encoding Object](#encoding-object).
2192+
* Use the Example Object's `serializedValue` if the serialization can be represented as a valid Unicode string, and there is no need to demonstrate the exact character encoding to be used.
2193+
* Use the string form of `value` only if compatibility with OAS v3.1 or earlier is needed.
2194+
* Use the Example Object's `externalValue` for all other values, or if it is desirable to maintain the example separately from the OpenAPI document.
21702195

2171-
The singular `example` field in the Parameter, Header, or Media Type Object is concise and convenient for simple examples, but does not offer any other advantages over using Example Objects under `examples`.
2196+
The `serializedValue` and `externalValue` fields both MUST show the serialized form of the data.
2197+
For Media Type Objects, this is a document of the appropriate media type, with any Encoding Object effects applied.
2198+
For Parameter and Header Objects using `schema` and `style` rather than a Media Type Object, see [Style Examples](#style-examples) for what constitutes a serialized value.
2199+
2200+
###### Criteria for `serializedExample`
2201+
2202+
A serialization can be represented as a valid Unicode string in `serializedValue` if any of the following are true of the serialization:
2203+
2204+
* It is for a media type that supports a `charset` parameter that indicates any Unicode encoding (UTF-8, UTF-16, etc.), or any valid subset of such an encoding, such as US-ASCII.
2205+
* It is for a format (such as URIs or HTTP fields) or character-based media type that requires or defaults to a Unicode encoding, or any valid subset of such an encoding, such as US-ASCII, and this is not overridden by `charset`.
2206+
* It is for a compound format where all parts meet at least one of the above criteria, e.g. a `multipart/mixed` media type with parts that are `application/json` (a media type that defaults to UTF-8) and `application/xml; charset=utf-8` (a media type with an explicit `charset` parameter).
2207+
2208+
In all of these cases, the conversion from the character set of the OAD (presumed to be UTF-8 as the only interoperable character set for JSON, and therefore also for JSON-compatible YAML as noted in [[RFC9512]] [Section 3.4](https://www.rfc-editor.org/rfc/rfc9512.html#section-3.4)) first to Unicode code points and then to the actual serialization character set is well-defined.
2209+
2210+
For `externalValue`, if the character set is neither explicitly stated nor determined by the format or media type specification, implementations SHOULD assume UTF-8.
2211+
2212+
###### Validating Examples
2213+
2214+
Tooling implementations MAY choose to validate compatibility automatically, and reject the example value(s) if incompatible.
2215+
For examples that are in schema-ready data form, this is straightforward.
21722216

2173-
Some examples cannot be represented directly in JSON or YAML.
2174-
For all three ways of providing examples, these can be shown as string values with any escaping necessary to make the string valid in the JSON or YAML format of documents that comprise the OpenAPI Description.
2175-
With the Example Object, such values can alternatively be handled through the `externalValue` field.
2217+
With serialized examples, some formats allow multiple possible valid representations of the same data, including in scenarios noted in [Appendix B](#appendix-b-data-type-conversion).
2218+
In some cases, parsing the serialized example and validating the resulting data can eliminate the ambiguity, but in a few cases parsing is also ambiguous.
2219+
Therefore, OAD authors are cautioned that validation of certain serialized examples is by necessity a best-effort feature.
21762220

21772221
##### Example Object Examples
21782222

src/schemas/validation/schema.yaml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -672,14 +672,30 @@ $defs:
672672
type: string
673673
description:
674674
type: string
675+
dataValue: true
676+
serializedValue:
677+
type: string
675678
value: true
676679
externalValue:
677680
type: string
678681
format: uri-reference
679-
not:
680-
required:
681-
- value
682-
- externalValue
682+
allOf:
683+
- not:
684+
required:
685+
- value
686+
- externalValue
687+
- not:
688+
required:
689+
- value
690+
- dataValue
691+
- not:
692+
required:
693+
- value
694+
- serializedValue
695+
- not:
696+
required:
697+
- serializedValue
698+
- externalValue
683699
$ref: '#/$defs/specification-extensions'
684700
unevaluatedProperties: false
685701

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: 3.2.0
2+
info:
3+
title: API
4+
version: 1.0.0
5+
6+
components:
7+
examples:
8+
CannotHaveBoth:
9+
value: foo
10+
externalValue: https://example.com/foo
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: 3.2.0
2+
info:
3+
title: API
4+
version: 1.0.0
5+
6+
components:
7+
examples:
8+
NoValueWithDataValue:
9+
value: foo
10+
dataValue: foo
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: 3.2.0
2+
info:
3+
title: API
4+
version: 1.0.0
5+
6+
components:
7+
examples:
8+
CannotHaveBoth:
9+
value: foo
10+
serializedValue: foo
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: 3.2.0
2+
info:
3+
title: API
4+
version: 1.0.0
5+
6+
components:
7+
examples:
8+
CannotHaveBoth:
9+
serializedValue: foo
10+
externalValue: https://example.com/foo

tests/schema/pass/example-object-examples.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,5 @@ components:
6060
examples:
6161
jsonFormValue:
6262
description: 'The JSON string "json" as a form value'
63-
value: jsonValue=%22json%22
63+
dataValue: json
64+
serializedValue: jsonValue=%22json%22

0 commit comments

Comments
 (0)