Skip to content

Commit 01ec4b7

Browse files
authored
Merge pull request #5196 from karenetheridge/ether/3.2-parameter-styles-more
v3.2: edits to parameter sections
2 parents 1c07626 + f2c18be commit 01ec4b7

11 files changed

Lines changed: 247 additions & 44 deletions

src/oas.md

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -769,14 +769,14 @@ See [Appendix E](#appendix-e-percent-encoding-and-form-media-types) for a detail
769769
There are five possible parameter locations specified by the `in` field:
770770

771771
* path - Used together with [Path Templating](#path-templating), where the parameter value is actually part of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, the path parameter is `itemId`.
772-
* query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`; MUST NOT appear in the same operation (or in the operation's path-item) as an `in: "querystring"` parameter.
772+
* query - Parameters that are appended to the URL with the `?` character (or for subsequent query parameters, with the `&` character); MUST NOT appear in the same operation (or in the operation's path-item) as an `in: "querystring"` parameter.
773773
* querystring - A parameter that treats the entire URL query string as a value which MUST be specified using the `content` field, most often with media type `application/x-www-form-urlencoded` using [Encoding Objects](#encoding-object) in the same way as with request bodies of that media type; MUST NOT appear more than once, and MUST NOT appear in the same operation (or in the operation's path-item) as any `in: "query"` parameters.
774774
* header - Custom headers that are expected as part of the request. Note that [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#section-5.1) states header names are case-insensitive.
775775
* cookie - Used to pass a specific cookie value to the API.
776776

777777
#### Fixed Fields
778778

779-
The rules for serialization of the parameter are specified in one of two ways.
779+
The rules for serialization and deserialization of the parameter are specified in one of two ways.
780780
Parameter Objects MUST include either a `content` field or a `schema` field, but not both.
781781
See [Appendix B](#appendix-b-data-type-conversion) for a discussion of converting values of various types to string representations.
782782

@@ -819,8 +819,8 @@ In these cases, implementations MUST pass values through unchanged rather than a
819819
| ---- | :----: | ---- |
820820
| <a name="parameter-style"></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"` (for compatibility reasons; note that `style: "cookie"` SHOULD be used with `in: "cookie"`; see [Appendix D](#appendix-d-serializing-headers-and-cookies) for details). |
821821
| <a name="parameter-explode"></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, or when [`style`](#parameter-style) is `"deepObject"`, this field has no effect. When `style` is `"form"` or `"cookie"`, the default value is `true`. For all other styles, the default value is `false`. |
822-
| <a name="parameter-allow-reserved"></a>allowReserved | `boolean` | When this is true, parameter values are serialized using reserved expansion, as defined by [RFC6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3), which allows [RFC3986's reserved character set](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2), as well as percent-encoded triples, to pass through unchanged, while still percent-encoding all other disallowed characters (including `%` outside of percent-encoded triples). Applications are still responsible for percent-encoding reserved characters that are not allowed by the rules of the `in` destination or media type, or are [not allowed in the path by this specification](#path-templating); see [URL Percent-Encoding](#url-percent-encoding) for details. The default value is `false`. This field only applies to `in` and `style` values that automatically percent-encode. |
823-
| <a name="parameter-schema"></a>schema | [Schema Object](#schema-object) | The schema defining the type used for the parameter. |
822+
| <a name="parameter-allow-reserved"></a>allowReserved | `boolean` | When this is true, parameter values are serialized using reserved expansion, as defined by [RFC6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3), which allows [RFC3986's reserved character set](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2), as well as percent-encoded triples, to pass through unchanged, while still percent-encoding all other disallowed characters (including `%` outside of percent-encoded triples). Applications are still responsible for percent-encoding reserved characters that are not allowed by the rules of the `in` destination or media type, or are [not allowed in the path by this specification](#path-templating); see [URL Percent-Encoding](#url-percent-encoding) for details. The default value is `false`. This field only applies to `in` and `style` values that automatically percent-encode (that is: `in: path`, `in: query`, and `in: cookie` with `style: form`). |
823+
| <a name="parameter-schema"></a>schema | [Schema Object](#schema-object) | The schema defining the type and other constraints used for the parameter. |
824824

825825
See also [Appendix C: Using RFC6570-Based Serialization](#appendix-c-using-rfc6570-based-serialization) for additional guidance.
826826

@@ -923,19 +923,19 @@ The following table shows serialized examples, as would be shown with the `seria
923923
| label | true | _empty_ | .blue | .blue.black.brown | .R=100.G=200.B=150 |
924924
| simple | false | _empty_ | blue | blue,black,brown | R,100,G,200,B,150 |
925925
| simple | true | _empty_ | blue | blue,black,brown | R=100,G=200,B=150 |
926-
| form | false | <span style="white-space: nowrap;">color=</span> | <span style="white-space: nowrap;">color=blue</span> | <span style="white-space: nowrap;">color=blue,black,brown</span> | <span style="white-space: nowrap;">color=R,100,G,200,B,150</span> |
927-
| form | true | <span style="white-space: nowrap;">color=</span> | <span style="white-space: nowrap;">color=blue</span> | <span style="white-space: nowrap;">color=blue&color=black&color=brown</span> | <span style="white-space: nowrap;">R=100&G=200&B=150</span> |
928-
| spaceDelimited</span> | false | _n/a_ | _n/a_ | <span style="white-space: nowrap;">color=blue%20black%20brown</span> | <span style="white-space: nowrap;">color=R%20100%20G%20200%20B%20150</span> |
926+
| form | false | color= | color=blue | color=blue,black,brown | color=R,100,G,200,B,150 |
927+
| form | true | color= | color=blue | color=blue&color=black&color=brown | R=100&G=200&B=150 |
928+
| spaceDelimited | false | _n/a_ | _n/a_ | color=blue%20black%20brown | color=R%20100%20G%20200%20B%20150 |
929929
| spaceDelimited | true | _n/a_ | _n/a_ | _n/a_ | _n/a_ |
930-
| pipeDelimited | false | _n/a_ | _n/a_ | <span style="white-space: nowrap;">color=blue%7Cblack%7Cbrown</span> | <span style="white-space: nowrap;">color=R%7C100%7CG%7C200%7CB%7C150</span> |
930+
| pipeDelimited | false | _n/a_ | _n/a_ | color=blue%7Cblack%7Cbrown | color=R%7C100%7CG%7C200%7CB%7C150 |
931931
| pipeDelimited | true | _n/a_ | _n/a_ | _n/a_ | _n/a_ |
932-
| deepObject | _n/a_ | _n/a_ | _n/a_ | _n/a_ | <span style="white-space: nowrap;">color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150</span> |
933-
| cookie | false | <span style="white-space: nowrap;">color=</span> | <span style="white-space: nowrap;">color=blue</span> | <span style="white-space: nowrap;">color=blue,black,brown</span> | <span style="white-space: nowrap;">color=R,100,G,200,B,150</span> |
934-
| cookie | true | <span style="white-space: nowrap;">color=</span> | <span style="white-space: nowrap;">color=blue</span> | <span style="white-space: nowrap;">color=blue; color=black; color=brown</span> | <span style="white-space: nowrap;">R=100; G=200; B=150</span> |
932+
| deepObject | _n/a_ | _n/a_ | _n/a_ | _n/a_ | color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150 |
933+
| cookie | false | color= | color=blue | color=blue,black,brown | color=R,100,G,200,B,150 |
934+
| cookie | true | color= | color=blue | color=blue; color=black; color=brown | R=100; G=200; B=150 |
935935

936936
#### Extending Support for Querystring Formats
937937

938-
Many frameworks define query string syntax for complex values, such as appending array indices to parameter names or indicating multiple levels of of nested objects, which go well beyond the capabilities of the `deepObject` style.
938+
Many frameworks define query string syntax for complex values, such as appending array indices to parameter names or indicating multiple levels of nested objects, which go well beyond the capabilities of the `deepObject` style.
939939

940940
As these are not standards, and often contradict each other, the OAS does not attempt to support them directly.
941941
Two avenues are available for supporting such formats with `in: "querystring"`:
@@ -1070,7 +1070,7 @@ examples:
10701070
dataValue:
10711071
page: 4
10721072
pageSize: 50
1073-
serializeValue: page=4&pageSize=50
1073+
serializedValue: page=4&pageSize=50
10741074
```
10751075
10761076
A complex parameter using `content` to define serialization, with multiple levels and types of examples shown to make the example usage options clear — note that `dataValue` is the same at both levels and does not need to be shown in both places in normal usage, but `serializedValue` is different:
@@ -1091,15 +1091,17 @@ content:
10911091
long:
10921092
type: number
10931093
examples:
1094-
dataValue:
1095-
lat: 10
1096-
long: 60
1097-
serializedValue: '{"lat":10,"long":60}'
1094+
'New York':
1095+
dataValue:
1096+
lat: 40.6
1097+
long: -73.9
1098+
serializedValue: '{"lat":40.6,"long":-73.9}'
10981099
examples:
1099-
dataValue:
1100-
lat: 10
1101-
long: 60
1102-
serializedValue: coordinates=%7B%22lat%22%3A10%2C%22long%22%3A60%7D
1100+
'New York':
1101+
dataValue:
1102+
lat: 40.6
1103+
long: -73.9
1104+
serializedValue: coordinates=%7B%22lat%22%3A40.6%2C%22long%22%3A-73.9%7D
11031105
```
11041106

11051107
A querystring parameter using regular form encoding, but managed with a Media Type Object.
@@ -1108,6 +1110,7 @@ Examples are shown at both the media type and parameter level to emphasize that,
11081110

11091111
```yaml
11101112
in: querystring
1113+
name: metadata
11111114
content:
11121115
application/x-www-form-urlencoded:
11131116
schema:
@@ -2383,7 +2386,7 @@ The `serializedValue` and `externalValue` fields both MUST show the serialized f
23832386
For Media Type Objects, this is a document of the appropriate media type, with any Encoding Object effects applied.
23842387
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.
23852388

2386-
##### Criteria for `serializedExample`
2389+
##### Criteria for `serializedValue`
23872390

23882391
A serialization can be represented as a valid Unicode string in `serializedValue` if any of the following are true of the serialization:
23892392

@@ -2858,7 +2861,7 @@ components:
28582861
In an HTTP message, the serialized example would look like:
28592862
28602863
```http
2861-
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GM
2864+
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
28622865
Set-Cookie: foo=bar; Expires=Wed, 09 Jun 2021 10:18:14 GMT
28632866
Set-Cookie: urlSafeData=Hello%2C%20world%21
28642867
```
@@ -4449,8 +4452,7 @@ application/xml:
44494452
- Some text
44504453
- unit: cubits
44514454
value: 42
4452-
null
4453-
]
4455+
- null
44544456
externalValue: ./examples/OneTwoThree.xml
44554457
```
44564458

@@ -4909,7 +4911,7 @@ parameters:
49094911
type: string
49104912
```
49114913

4912-
This example is equivalent to RFC6570's `{?foo*,bar}`, and **NOT** `{?foo*}{&bar}`. The latter is problematic because if `foo` is not defined, the result will be an invalid URI.
4914+
This example is equivalent to RFC6570's `{?foo*,bar}`, and **NOT** `{?foo*}{&bar}`. The latter is problematic because if `foo` is not defined (see [RFC6570 §2.3](https://www.rfc-editor.org/rfc/rfc6570#section-2.3) for details on what is considered undefined), the result will be an invalid URI.
49134915
The `&` prefix operator has no equivalent in the Parameter Object.
49144916

49154917
Note that RFC6570 does not specify behavior for compound values beyond the single level addressed by `explode`. The result of using objects or arrays where no behavior is clearly specified for them is implementation-defined.
@@ -4971,6 +4973,7 @@ parameters:
49714973
type: array
49724974
items:
49734975
type: string
4976+
explode: false
49744977
```
49754978
49764979
This translates to the following URI Template:

src/schemas/validation/schema.yaml

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -421,15 +421,11 @@ $defs:
421421
type: string
422422
explode:
423423
type: boolean
424-
allowReserved:
425-
default: false
426-
type: boolean
427424
allOf:
428425
- $ref: '#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path'
429426
- $ref: '#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header'
430427
- $ref: '#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query'
431428
- $ref: '#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie'
432-
- $ref: '#/$defs/styles-for-form'
433429

434430
$defs:
435431
styles-for-path:
@@ -439,6 +435,8 @@ $defs:
439435
const: path
440436
then:
441437
properties:
438+
name:
439+
pattern: '^[^{}]+$'
442440
style:
443441
default: simple
444442
enum:
@@ -447,6 +445,11 @@ $defs:
447445
- simple
448446
required:
449447
const: true
448+
explode:
449+
default: false
450+
allowReserved:
451+
type: boolean
452+
default: false
450453
required:
451454
- required
452455

@@ -460,6 +463,8 @@ $defs:
460463
style:
461464
default: simple
462465
const: simple
466+
explode:
467+
default: false
463468

464469
styles-for-query:
465470
if:
@@ -475,6 +480,10 @@ $defs:
475480
- spaceDelimited
476481
- pipeDelimited
477482
- deepObject
483+
allowReserved:
484+
type: boolean
485+
default: false
486+
$ref: '#/$defs/explode-for-form'
478487

479488
styles-for-cookie:
480489
if:
@@ -488,6 +497,17 @@ $defs:
488497
enum:
489498
- form
490499
- cookie
500+
explode:
501+
default: true
502+
if:
503+
properties:
504+
style:
505+
const: form
506+
then:
507+
properties:
508+
allowReserved:
509+
type: boolean
510+
default: false
491511

492512
unevaluatedProperties: false
493513

@@ -615,6 +635,7 @@ $defs:
615635
properties:
616636
allowReserved:
617637
default: false
638+
$ref: '#/$defs/explode-for-form'
618639
explode:
619640
properties:
620641
style:
@@ -625,9 +646,8 @@ $defs:
625646
properties:
626647
style:
627648
default: form
628-
allOf:
629-
- $ref: '#/$defs/specification-extensions'
630-
- $ref: '#/$defs/styles-for-form'
649+
$ref: '#/$defs/explode-for-form'
650+
$ref: '#/$defs/specification-extensions'
631651
unevaluatedProperties: false
632652

633653
responses:
@@ -808,9 +828,6 @@ $defs:
808828
explode:
809829
default: false
810830
type: boolean
811-
allowReserved:
812-
default: false
813-
type: boolean
814831
allOf:
815832
- $ref: '#/$defs/examples'
816833
- $ref: '#/$defs/specification-extensions'
@@ -1118,13 +1135,12 @@ $defs:
11181135
additionalProperties:
11191136
type: string
11201137

1121-
styles-for-form:
1138+
explode-for-form:
1139+
$comment: for encoding objects, and query and cookie parameters, style=form is the default
11221140
if:
11231141
properties:
11241142
style:
11251143
const: form
1126-
required:
1127-
- style
11281144
then:
11291145
properties:
11301146
explode:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.2.0
2+
info:
3+
title: allowReserved only permitted with in and style values that percent-encode
4+
version: 1.0.0
5+
components:
6+
headers:
7+
Style:
8+
schema:
9+
type: array
10+
style: simple
11+
explode: true
12+
allowReserved: true
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.2.0
2+
info:
3+
title: allowReserved only permitted with in and style values that percent-encode
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
my_cookie:
8+
name: my_cookie
9+
in: cookie
10+
style: cookie
11+
allowReserved: true
12+
schema: {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
openapi: 3.2.0
2+
info:
3+
title: allowReserved only permitted with in and style values that percent-encode
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
header:
8+
name: my-header
9+
in: header
10+
allowReserved: false
11+
schema: {}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ components:
2323
type: array
2424
style: simple
2525
explode: true
26-
allowReserved: true
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
openapi: 3.2.0
2+
info:
3+
title: allowReserved only permitted with in and style values that percent-encode
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
style_form:
8+
name: my_form_cookie
9+
in: cookie
10+
# default style is form, therefore allowReserved is allowed
11+
allowReserved: true
12+
schema: {}
13+
style_cookie:
14+
name: my_cookie_cookie
15+
in: cookie
16+
style: cookie
17+
# no percent decoding for style=cookie, therefore allowReserved is not allowed
18+
schema: {}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@ paths:
99
in: header
1010
description: token to be passed as a header
1111
required: true
12+
explode: false
1213
schema:
1314
type: array
1415
items:
1516
type: integer
1617
format: int64
1718
style: simple
18-
- name: username
19+
- name: usernames
1920
in: path
20-
description: username to fetch
21+
description: usernames to fetch
2122
required: true
23+
explode: false
2224
schema:
23-
type: string
25+
type: array
2426
- name: id
2527
in: query
26-
description: ID of the object to fetch
28+
description: IDs of the object to fetch
2729
required: false
2830
schema:
2931
type: array
@@ -55,10 +57,12 @@ paths:
5557
- in: cookie
5658
name: my_cookie1
5759
style: form
60+
explode: false
5861
schema: {}
5962
- in: cookie
6063
name: my_cookie2
6164
style: cookie
65+
explode: true
6266
schema: {}
6367
/user:
6468
parameters:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.2.0
2+
info:
3+
title: api
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
path:
8+
name: my-path
9+
in: path
10+
required: true
11+
allowReserved: false
12+
schema: {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
openapi: 3.2.0
2+
info:
3+
title: allowReserved only permitted with in and style values that percent-encode
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
my_query:
8+
name: my_query
9+
in: query
10+
allowReserved: true
11+
schema: {}

0 commit comments

Comments
 (0)