Skip to content

v3.2: Allow Media Type and Encoding re-use #4728

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

Open
wants to merge 1 commit into
base: v3.2-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 9 additions & 5 deletions src/oas.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ All objects defined within the Components Object will have no effect on the API
| <a name="components-links"></a> links | Map[`string`, [Link Object](#link-object) \| [Reference Object](#reference-object)] | An object to hold reusable [Link Objects](#link-object). |
| <a name="components-callbacks"></a> callbacks | Map[`string`, [Callback Object](#callback-object) \| [Reference Object](#reference-object)] | An object to hold reusable [Callback Objects](#callback-object). |
| <a name="components-path-items"></a> pathItems | Map[`string`, [Path Item Object](#path-item-object)] | An object to hold reusable [Path Item Objects](#path-item-object). |
| <a name="components-media-types"></a> mediaTypes | Map[`string`, [Media Type Objects](#media-type-object) \| [Reference Object](#reference-object)] | An object to hold reusable [Media Type Objects](#media-type-object). |
| <a name="components-encodings"></a> encodings | Map[`string`, [Encoding Objects](#encoding-object) \| [Reference Object](#reference-object)] | An object to hold reusable [Encoding Objects](#encoding-object). |

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

Expand Down Expand Up @@ -1008,7 +1010,7 @@ For use with `in: "querystring"` and `application/x-www-form-urlencoded`, see [E

| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="parameter-content"></a>content | Map[`string`, [Media Type Object](#media-type-object)] | A map containing the representations for the parameter. The key is the media type and the value describes it. The map MUST only contain one entry. |
| <a name="parameter-content"></a>content | Map[`string`, [Media Type Object](#media-type-object) \| [Reference Object](#reference-object)] | A map containing the representations for the parameter. The key is the media type and the value describes it. The map MUST only contain one entry. |

##### Style Values

Expand Down Expand Up @@ -1198,7 +1200,7 @@ Describes a single request body.
| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="request-body-description"></a>description | `string` | A brief description of the request body. This could contain examples of use. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
| <a name="request-body-content"></a>content | Map[`string`, [Media Type Object](#media-type-object)] | **REQUIRED**. The content of the request body. The key is a media type or [media type range](https://www.rfc-editor.org/rfc/rfc9110.html#appendix-A) and the value describes it. The map SHOULD have at least one entry; if it does not, the behavior is implementation-defined. For requests that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` |
| <a name="request-body-content"></a>content | Map[`string`, [Media Type Object](#media-type-object) \| [Reference Object](#reference-object)] | **REQUIRED**. The content of the request body. The key is a media type or [media type range](https://www.rfc-editor.org/rfc/rfc9110.html#appendix-A) and the value describes it. The map SHOULD have at least one entry; if it does not, the behavior is implementation-defined. For requests that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` |
| <a name="request-body-required"></a>required | `boolean` | Determines if the request body is required in the request. Defaults to `false`. |

This object MAY be extended with [Specification Extensions](#specification-extensions).
Expand Down Expand Up @@ -1249,11 +1251,12 @@ See [Working With Examples](#working-with-examples) for further guidance regardi

| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="media-type-description"></a>description | `string` | A brief description of the media type. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
| <a name="media-type-schema"></a>schema | [Schema Object](#schema-object) | A schema describing the complete content of the request, response, parameter, or header. |
| <a name="media-type-item-schema"></a>itemSchema | [Schema Object](#schema-object) | A schema describing each item within a [sequential media type](#sequential-media-types). |
| <a name="media-type-example"></a>example | Any | Example of the media type; see [Working With Examples](#working-with-examples). |
| <a name="media-type-examples"></a>examples | Map[ `string`, [Example Object](#example-object) \| [Reference Object](#reference-object)] | Examples of the media type; see [Working With Examples](#working-with-examples). |
| <a name="media-type-encoding"></a>encoding | Map[`string`, [Encoding Object](#encoding-object)] | A map between a property name and its encoding information, as defined under [Encoding Usage and Restrictions](#encoding-usage-and-restrictions). The `encoding` field SHALL only apply 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. |
| <a name="media-type-encoding"></a>encoding | Map[`string`, [Encoding Object](#encoding-object) \| [Reference Object](#reference-object)] | A map between a property name and its encoding information, as defined under [Encoding Usage and Restrictions](#encoding-usage-and-restrictions). The `encoding` field SHALL only apply 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](#specification-extensions).

Expand Down Expand Up @@ -1639,6 +1642,7 @@ These fields MAY be used either with or without the RFC6570-style serialization

| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="encoding-description"></a>description | `string` | A brief description of the media type. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
| <a name="encoding-content-type"></a>contentType | `string` | The `Content-Type` for encoding a specific property. The value is a comma-separated list, each element of which is either a specific media type (e.g. `image/png`) or a wildcard media type (e.g. `image/*`). Default value depends on the property type as shown in the table below. |
| <a name="encoding-headers"></a>headers | Map[`string`, [Header Object](#header-object) \| [Reference Object](#reference-object)] | A map allowing additional information to be provided as headers. `Content-Type` is described separately and SHALL be ignored in this section. This field SHALL be ignored if the media type is not a `multipart`. |

Expand Down Expand Up @@ -1929,7 +1933,7 @@ Describes a single response from an API operation, including design-time, static
| <a name="response-summary"></a>summary | `string` | A short summary of the meaning of the response. |
| <a name="response-description"></a>description | `string` | A description of the response. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
| <a name="response-headers"></a>headers | Map[`string`, [Header Object](#header-object) \| [Reference Object](#reference-object)] | Maps a header name to its definition. [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#section-5.1) states header names are case insensitive. If a response header is defined with the name `"Content-Type"`, it SHALL be ignored. |
| <a name="response-content"></a>content | Map[`string`, [Media Type Object](#media-type-object)] | A map containing descriptions of potential response payloads. The key is a media type or [media type range](https://www.rfc-editor.org/rfc/rfc9110.html#appendix-A) and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` |
| <a name="response-content"></a>content | Map[`string`, [Media Type Object](#media-type-object) \| [Reference Object](#reference-object)] | A map containing descriptions of potential response payloads. The key is a media type or [media type range](https://www.rfc-editor.org/rfc/rfc9110.html#appendix-A) and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` |
| <a name="response-links"></a>links | Map[`string`, [Link Object](#link-object) \| [Reference Object](#reference-object)] | A map of operations links that can be followed from the response. The key of the map is a short name for the link, following the naming constraints of the names for [Component Objects](#components-object). |

This object MAY be extended with [Specification Extensions](#specification-extensions).
Expand Down Expand Up @@ -2449,7 +2453,7 @@ Using `content` with a `text/plain` media type is RECOMMENDED for headers where

| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="header-content"></a>content | Map[`string`, [Media Type Object](#media-type-object)] | A map containing the representations for the header. The key is the media type and the value describes it. The map MUST only contain one entry. |
| <a name="header-content"></a>content | Map[`string`, [Media Type Object](#media-type-object) \| [Reference Object](#reference-object)] | A map containing the representations for the header. The key is the media type and the value describes it. The map MUST only contain one entry. |

##### Header Object Example

Expand Down
38 changes: 35 additions & 3 deletions src/schemas/validation/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,16 @@ $defs:
type: object
additionalProperties:
$ref: '#/$defs/path-item'
mediaTypes:
type: object
additionalProperties:
$ref: '#/$defs/media-type-or-reference'
encodings:
type: object
additionalProperties:
$ref: '#/$defs/encoding-or-reference'
patternProperties:
'^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$':
'^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems|mediaTypes|encodings)$':
$comment: Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected
propertyNames:
pattern: '^[a-zA-Z0-9._-]+$'
Expand Down Expand Up @@ -517,31 +525,45 @@ $defs:
$comment: https://spec.openapis.org/oas/v3.2#fixed-fields-10
type: object
additionalProperties:
$ref: '#/$defs/media-type'
$ref: '#/$defs/media-type-or-reference'
propertyNames:
format: media-range

media-type:
$comment: https://spec.openapis.org/oas/v3.2#media-type-object
type: object
properties:
description:
type: string
schema:
$dynamicRef: '#meta'
itemSchema:
$dynamicRef: '#meta'
encoding:
type: object
additionalProperties:
$ref: '#/$defs/encoding'
$ref: '#/$defs/encoding-or-reference'
allOf:
- $ref: '#/$defs/specification-extensions'
- $ref: '#/$defs/examples'
unevaluatedProperties: false

media-type-or-reference:
if:
type: object
required:
- $ref
then:
$ref: '#/$defs/reference'
else:
$ref: '#/$defs/media-type'

encoding:
$comment: https://spec.openapis.org/oas/v3.2#encoding-object
type: object
properties:
description:
type: string
contentType:
type: string
format: media-range
Expand All @@ -566,6 +588,16 @@ $defs:
- $ref: '#/$defs/styles-for-form'
unevaluatedProperties: false

encoding-or-reference:
if:
type: object
required:
- $ref
then:
$ref: '#/$defs/reference'
else:
$ref: '#/$defs/encoding'

responses:
$comment: https://spec.openapis.org/oas/v3.2#responses-object
type: object
Expand Down
28 changes: 23 additions & 5 deletions tests/schema/pass/media-type-examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,25 @@ openapi: 3.2.0
info:
title: API
version: 1.0.0
components:
mediaTypes:
StreamingPets:
description: |
Streaming sequence of JSON pet representations,
suitable for use with any of the streaming JSON
media types.
itemSchema:
$ref: '#components/schemas/Pet'
encodings:
ReservedNoExplode:
description: |
This allows multiple values under the same name,
and disables reserved percent-encoding.
Clients are responsible for adequately percent-encoding
the values in advance.
style: form
explode: false
allowReserved: true
paths:
/something:
put:
Expand Down Expand Up @@ -31,8 +50,9 @@ paths:
frog:
$ref: '#/components/examples/frog-example'
application/jsonl:
itemSchema:
$ref: '#components/schemas/Pet'
$ref: '#/components/mediaTypes/StreamingPets'
application/x-ndjson:
$ref: '#/components/mediaTypes/StreamingPets'
application/xml:
schema:
type: object
Expand Down Expand Up @@ -132,9 +152,7 @@ paths:
schema:
type: integer
forCoverage:
style: form
explode: false
allowReserved: true
$ref: '#/components/encodings/ReservedNoExplode'
forCoverage2:
style: spaceDelimited
explode: true