Skip to content

Commit

Permalink
Consolidate guidance around examples (3.1.1) (OAI#3893)
Browse files Browse the repository at this point in the history
The four ways of specifying parameter or media type examples
are confusing. There is a lot of guidance that is repeated,
making it harder to see the essentials.  Some of that guidance is
also contradictory, with most saying that the examples SHOULD
match various conditions, but one saying that they MUST.

Research shows that SHOULD was repeatedly advocated, and instances
of MUST corrected back to SHOULD, except for one final commit
where MUST was introduced, and the subsequent commit to revert
to SHOULD seems to have simply missed one instance.  So this
change takes the position that the MUST was an error and weakens
it to SHOULD to match the other four or five places where the
requirement was specified.
  • Loading branch information
handrews committed Jun 9, 2024
1 parent 6f8a0d7 commit 5ac50b3
Showing 1 changed file with 106 additions and 8 deletions.
114 changes: 106 additions & 8 deletions versions/3.1.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -1137,16 +1137,17 @@ Field Name | Type | Description
###### Fixed Fields for use with `schema`

For simpler scenarios, a [`schema`](#parameterSchema) and [`style`](#parameterStyle) can describe the structure and syntax of the parameter.
When `example` or `examples` are provided in conjunction with the `schema` object, the example MUST follow the prescribed serialization strategy for the parameter.
When `example` or `examples` are provided in conjunction with the `schema` object, the example SHOULD match the specified schema and follow the prescribed serialization strategy for the parameter.
The `example` and `examples` fields are mutually exclusive, and if either is present it SHALL _override_ any `example` in the schema.

Field Name | Type | Description
---|:---:|---
<a name="parameterStyle"></a>style | `string` | Describes how the parameter value will be serialized depending on the type of the parameter value. Default values (based on value of `in`): for `query` - `form`; for `path` - `simple`; for `header` - `simple`; for `cookie` - `form`.
<a name="parameterExplode"></a>explode | `boolean` | When this is true, parameter values of type `array` or `object` generate separate parameters for each value of the array or key-value pair of the map. For other types of parameters this property has no effect. When [`style`](#parameterStyle) is `form`, the default value is `true`. For all other styles, the default value is `false`.
<a name="parameterAllowReserved"></a>allowReserved | `boolean` | Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2) `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. This property only applies to parameters with an `in` value of `query`. The default value is `false`.
<a name="parameterSchema"></a>schema | [Schema Object](#schemaObject) | The schema defining the type used for the parameter.
<a name="parameterExample"></a>example | Any | Example of the parameter's potential value. The example SHOULD match the specified schema and encoding properties if present. The `example` field is mutually exclusive of the `examples` field. Furthermore, if referencing a `schema` that contains an example, the `example` value SHALL _override_ the example provided by the schema. To represent examples of media types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where necessary.
<a name="parameterExamples"></a>examples | Map[ `string`, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)] | Examples of the parameter's potential value. Each example SHOULD contain a value in the correct format as specified in the parameter encoding. The `examples` field is mutually exclusive of the `example` field. Furthermore, if referencing a `schema` that contains an example, the `examples` value SHALL _override_ the example provided by the schema.
<a name="parameterExample"></a>example | Any | Example of the parameter's potential value; see [Working With Examples](#working-with-examples).
<a name="parameterExamples"></a>examples | Map[ `string`, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)] | Examples of the parameter's potential value; see [Working With Examples](#working-with-examples).

###### Fixed Fields and considerations for use with `content`

Expand Down Expand Up @@ -1481,12 +1482,16 @@ content:
#### <a name="mediaTypeObject"></a>Media Type Object
Each Media Type Object provides schema and examples for the media type identified by its key.

When `example` or `examples` are provided, the example SHOULD match the specified schema and be in the correct format as specified by the media type and its encoding.
The `example` and `examples` fields are mutually exclusive, and if either is present it SHALL _override_ any `example` in the schema.
See [Working With Examples](#working-with-examples) for further guidance regarding the different ways of specifying examples, including non-JSON/YAML values.

##### Fixed Fields
Field Name | Type | Description
---|:---:|---
<a name="mediaTypeSchema"></a>schema | [Schema Object](#schemaObject) | The schema defining the content of the request, response, or parameter.
<a name="mediaTypeExample"></a>example | Any | Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The `example` field is mutually exclusive of the `examples` field. Furthermore, if referencing a `schema` which contains an example, the `example` value SHALL _override_ the example provided by the schema.
<a name="mediaTypeExamples"></a>examples | Map[ `string`, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)] | Examples of the media type. Each example object SHOULD match the media type and specified schema if present. The `examples` field is mutually exclusive of the `example` field. Furthermore, if referencing a `schema` which contains an example, the `examples` value SHALL _override_ the example provided by the schema.
<a name="mediaTypeExample"></a>example | Any | Example of the media type; see [Working With Examples](#working-with-examples).
<a name="mediaTypeExamples"></a>examples | Map[ `string`, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)] | Examples of the media type; see [Working With Examples](#working-with-examples).
<a name="mediaTypeEncoding"></a>encoding | Map[`string`, [Encoding Object](#encodingObject)] | A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding attribute SHALL only apply to [Request Body Objects](#requestBodyObject), and only when the media type is `multipart` or `application/x-www-form-urlencoded`. If no Encoding Object is provided for a property, the behavior is determined by the default values documented for the Encoding Object.

This object MAY be extended with [Specification Extensions](#specificationExtensions).
Expand Down Expand Up @@ -2078,9 +2083,28 @@ Field Name | Type | Description

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

In all cases, the example value is expected to be compatible with the type schema
of its associated value. Tooling implementations MAY choose to
validate compatibility automatically, and reject the example value(s) if incompatible.
In all cases, the example value SHOULD be compatible with the schema of its associated value.
Tooling implementations MAY choose to validate compatibility automatically, and reject the example value(s) if incompatible.

#### Working With Examples

Example Objects can be used in both [Parameter Objects](#parameterObject) and [Media Type Objects](#mediaTypeObject).
In both Objects, this is done through the `examples` (plural) field.
However, there are several other ways to provide examples: The `example` (singular) field that is mutually exclusive with `examples` in both Objects, and two keywords (the deprecated singular `example` and the current plural `examples`, which takes an array of examples) in the [Schema Object](#schemaObject) that appears in the `schema` field of both Objects.
Each of these fields has slightly different considerations.

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

The mutually exclusive fields in the Parameter 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 or within a media type representation.
The exact serialization and encoding is determined by various fields in the Parameter Object, or in the Media Type Object's [Encoding Object](#encodingObject).
Because examples using these fields represent the final serialized form of the data, they SHALL _override_ any `example` in the corresponding Schema Object.

The singular `example` field in the Parameter or Media Type object is concise and convenient for simple examples, but does not offer any other advantages over using Example Objects under `examples`.

Some examples cannot be represented directly in JSON or YAML.
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 the OpenAPI Description document.
With the Example Object, such values can alternatively be handled through the `externalValue` field.

##### Example Object Examples

Expand Down Expand Up @@ -2140,6 +2164,80 @@ responses:
$ref: '#/components/examples/confirmation-success'
```

Two different uses of JSON strings:

First, a request or response body that is just a JSON string (not an object containing a string):

```json
"application/json": {
"schema": {
"type": "string"
},
"examples": {
"jsonBody": {
"description": "A body of just the JSON string \"json\"",
"value": "json"
}
}
}
```

```yaml
application/json:
schema:
type: string
examples:
jsonBody:
description: 'A body of just the JSON string "json"'
value: json
```

In the above example, we can just show the JSON string (or any JSON value) as-is, rather than stuffing a serialized JSON value into a JSON string, which would have looked like `"\"json\""`.


In contrast, a JSON string encoded inside of a URL-style form body:

```json
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"properties": {
"jsonValue": {
"type": "string"
}
}
},
"encoding": {
"jsonValue": {
"contentType": "application/json"
}
},
"examples": {
"jsonFormValue": {
"description": "The JSON string \"json\" as a form value",
"value": "jsonValue=%22json%22"
}
}
}
```

```yaml
application/x-www-form-urlencoded:
schema:
type: object
properties:
jsonValue:
type: string
encoding:
jsonValue:
contentType: application/json
examples:
jsonFormValue:
description: 'The JSON string "json" as a form value'
value: jsonValue=%22json%22
```

In this example, the JSON string had to be serialized before encoding it into the URL form value, so the example includes the quotation marks that are part of the JSON serialization, which are then URL percent-encoded.

#### <a name="linkObject"></a>Link Object

Expand Down

0 comments on commit 5ac50b3

Please sign in to comment.