diff --git a/src/oas.md b/src/oas.md index e91c9cb08a..ab75857cce 100644 --- a/src/oas.md +++ b/src/oas.md @@ -1641,6 +1641,9 @@ These fields MAY be used either with or without the RFC6570-style serialization | ---- | :----: | ---- | | 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. | | 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`. | +| encoding | Map[`string`, [Encoding Object](#encoding-object)] | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `encoding` field. | +| prefixEncoding | [[Encoding Object](#encoding-object)] | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `prefixEncoding` field. | +| itemEncoding | [Encoding Object](#encoding-object) | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `itemEncoding` field. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -1674,6 +1677,11 @@ See also [Appendix C: Using RFC6570 Implementations](#appendix-c-using-rfc6570-b Note that the presence of at least one of `style`, `explode`, or `allowReserved` with an explicit value is equivalent to using `schema` with `in: "query"` Parameter Objects. The absence of all three of those fields is the equivalent of using `content`, but with the media type specified in `contentType` rather than through a Media Type Object. +##### Nested Encoding + +Nested formats requiring encoding, most notably nested `multipart/mixed`, can be supported with this Object's `encoding`, `prefixEncoding`, and / or `itemEncoding` fields. +Implementations MUST support one level of nesting, and MAY support additional levels. + ##### Encoding the `x-www-form-urlencoded` Media Type To work with content using form url encoding via [RFC1866](https://tools.ietf.org/html/rfc1866), use the `application/x-www-form-urlencoded` media type in the [Media Type Object](#media-type-object). @@ -1869,6 +1877,31 @@ requestBody: As seen in the [Encoding Object's `contentType` field documentation](#encoding-content-type), the empty schema for `items` indicates a media type of `application/octet-stream`. +###### Example: Nested `multipart/mixed` + +This defines a two-part `multipart/mixed` where the first part is a JSON array and the second part is a nested `multipart/mixed` document. +The nested parts are XML, plain text, and a PNG image. + +```yaml +multipart/mixed: + schema: + type: array + prefixItems: + - type: array + - type: array + prefixItems: + - type: object + - type: string + - {} + prefixEncoding: + - {} # Accept the default application/json + - contentType: multipart/mixed + prefixEncoding: + - contentType: application/xml + - {} # Accept the default text/plain + - contentType: image/png +``` + #### Responses Object A container for the expected responses of an operation. diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml index 9990fefb67..d79902c765 100644 --- a/src/schemas/validation/schema.yaml +++ b/src/schemas/validation/schema.yaml @@ -561,9 +561,24 @@ $defs: allowReserved: default: false type: boolean + encoding: + type: object + additionalProperties: + $ref: '#/$defs/encoding' + prefixEncoding: + type: array + items: + $ref: '#/$defs/encoding' + itemEncoding: + $ref: '#/$defs/encoding' allOf: - $ref: '#/$defs/specification-extensions' - $ref: '#/$defs/styles-for-form' + - dependentSchemas: + encoding: + properties: + prefixEncoding: false + itemEncoding: false unevaluatedProperties: false responses: diff --git a/tests/schema/fail/encoding-enc-item-exclusion.yaml b/tests/schema/fail/encoding-enc-item-exclusion.yaml new file mode 100644 index 0000000000..658f848be9 --- /dev/null +++ b/tests/schema/fail/encoding-enc-item-exclusion.yaml @@ -0,0 +1,12 @@ +openapi: 3.2.0 +info: + title: API + version: 1.0.0 +components: + requestBodies: + content: + multipart/mixed: + prefixEncoding: + - contentType: multipart/mixed + encoding: {} + prefixEncoding: [] diff --git a/tests/schema/fail/encoding-enc-prefix-exclusion.yaml b/tests/schema/fail/encoding-enc-prefix-exclusion.yaml new file mode 100644 index 0000000000..8f62070d3b --- /dev/null +++ b/tests/schema/fail/encoding-enc-prefix-exclusion.yaml @@ -0,0 +1,12 @@ +openapi: 3.2.0 +info: + title: API + version: 1.0.0 +components: + requestBodies: + content: + multipart/mixed: + prefixEncoding: + - contentType: multipart/mixed + encoding: {} + itemEncoding: [] diff --git a/tests/schema/pass/media-type-examples.yaml b/tests/schema/pass/media-type-examples.yaml index 2ab4e68076..72470f82e0 100644 --- a/tests/schema/pass/media-type-examples.yaml +++ b/tests/schema/pass/media-type-examples.yaml @@ -117,6 +117,10 @@ paths: type: string forCoverage2: type: string + nested1: + type: object + nested2: + type: array encoding: addresses: # require XML Content-Type in utf-8 encoding @@ -138,3 +142,12 @@ paths: forCoverage2: style: spaceDelimited explode: true + nested1: + contentType: multipart/form-data + encoding: + inner: {} + nested2: + contentType: multipart/mixed + prefixEncoding: + - {} + itemEncoding: {}