Skip to content

v3.2: Add in: "querystring" parameter location treating the entire query string as one chunk of content #4590

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 2 commits 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
54 changes: 51 additions & 3 deletions src/oas.md
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,8 @@ See [Appendix E](#appendix-e-percent-encoding-and-form-media-types) for a detail
There are four possible parameter locations specified by the `in` field:

* 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`.
* query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`.
* 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 as an `in: "querystring"` parameter.
* 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 with any `in: "query"` parameters.
* 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.
* cookie - Used to pass a specific cookie value to the API.

Expand All @@ -921,8 +922,8 @@ These fields MAY be used with either `content` or `schema`.

| Field Name | Type | Description |
| ---- | :----: | ---- |
| <a name="parameter-name"></a>name | `string` | **REQUIRED**. The name of the parameter. Parameter names are _case sensitive_. <ul><li>If [`in`](#parameter-in) is `"path"`, the `name` field MUST correspond to a template expression occurring within the [path](#paths-path) field in the [Paths Object](#paths-object). See [Path Templating](#path-templating) for further information.<li>If [`in`](#parameter-in) is `"header"` and the `name` field is `"Accept"`, `"Content-Type"` or `"Authorization"`, the parameter definition SHALL be ignored.<li>For all other cases, the `name` corresponds to the parameter name used by the [`in`](#parameter-in) field.</ul> |
| <a name="parameter-in"></a>in | `string` | **REQUIRED**. The location of the parameter. Possible values are `"query"`, `"header"`, `"path"` or `"cookie"`. |
| <a name="parameter-name"></a>name | `string` | **REQUIRED**. The name of the parameter. Parameter names are _case sensitive_. <ul><li>If [`in`](#parameter-in) is `"path"`, the `name` field MUST correspond to a template expression occurring within the [path](#paths-path) field in the [Paths Object](#paths-object). See [Path Templating](#path-templating) for further information.<li>If [`in`](#parameter-in) is `"header"` and the `name` field is `"Accept"`, `"Content-Type"` or `"Authorization"`, the parameter definition SHALL be ignored.<li>If `in` is `"querystring"`, or for [certain combinations](#style-examples) of [`style`](#parameter-style) and [`explode`](#parameter-explode), the value of `name` is not used in the parameter serialization.<li>For all other cases, the `name` corresponds to the parameter name used by the [`in`](#parameter-in) field.</ul> |
| <a name="parameter-in"></a>in | `string` | **REQUIRED**. The location of the parameter. Possible values are `"query"`, `"querystring"`, `"header"`, `"path"` or `"cookie"`. |
| <a name="parameter-description"></a>description | `string` | A brief description of the parameter. This could contain examples of use. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
| <a name="parameter-required"></a>required | `boolean` | Determines whether this parameter is mandatory. If the [parameter location](#parameter-in) is `"path"`, this field is **REQUIRED** and its value MUST be `true`. Otherwise, the field MAY be included and its default value is `false`. |
| <a name="parameter-deprecated"></a> deprecated | `boolean` | Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is `false`. |
Expand All @@ -938,6 +939,8 @@ For simpler scenarios, a [`schema`](#parameter-schema) and [`style`](#parameter-
When `example` or `examples` are provided in conjunction with the `schema` field, 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.

These fields MUST NOT be used with `in: "querystring"`.

Serializing with `schema` is NOT RECOMMENDED for `in: "cookie"` parameters, `in: "header"` parameters that use HTTP header parameters (name=value pairs following a `;`) in their values, or `in: "header"` parameters where values might have non-URL-safe characters; see [Appendix D](#appendix-d-serializing-headers-and-cookies) for details.

| Field Name | Type | Description |
Expand All @@ -956,6 +959,8 @@ See also [Appendix C: Using RFC6570-Based Serialization](#appendix-c-using-rfc65
For more complex scenarios, the [`content`](#parameter-content) field can define the media type and schema of the parameter, as well as give examples of its use.
Using `content` with a `text/plain` media type is RECOMMENDED for `in: "header"` and `in: "cookie"` parameters where the `schema` strategy is not appropriate.

For use with `in: "querystring"` and `application/x-www-form-urlencoded`, see [Encoding the `x-www-form-urlencoded` Media Type](#encoding-the-x-www-form-urlencoded-media-type).

| 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. |
Expand Down Expand Up @@ -1012,6 +1017,16 @@ The following table shows examples, as would be shown with the `example` or `exa
| deepObject | false | _n/a_ | _n/a_ | _n/a_ | _n/a_ |
| deepObject | true | _n/a_ | _n/a_ | _n/a_ | <span style="white-space: nowrap;">?color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150</span> |

##### Extending Support for Querystring Formats

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.

As these are not standards, and often contradict each other, the OAS does not attempt to support them directly.
Two avenues are available for supporting such formats with `in: "querystring"`:

* Use `content` and `text/plain` with a schema of `type: "string"` and define the format outside of OpenAPI. While this requires more work to document and construct or parse the format, which is seen as a plain string from the OpenAPI perspective, it provides the easiest flexible option
* Define a media type (which need not necessarily be [IANA-registered](https://www.rfc-editor.org/rfc/rfc6838.html)) and submit a registration for how it can be supported (using `in: "querystring"` and the `content` field) to the OpenAPI Initiative's [Media Type Registry](#media-type-registry).

##### Parameter Object Examples

A header parameter with an array of 64-bit integer numbers:
Expand Down Expand Up @@ -1086,6 +1101,39 @@ content:
type: number
```

A querystring parameter that uses JSON for the entire string (not as a single query parameter value):

```yaml
in: querystring
name: json
content:
application/json:
schema:
# Allow an arbitrary JSON object to keep
# the example simple
type: object
```

A querystring parameter that uses JSONPath:

```yaml
in: querystring
name: sql
content:
application/jsonpath:
schema:
type: string
example: $.a.b[1:1]
```

As there is not currently a defined mapping between the JSON Schema data model and JSONPath, the details of the string's allowed structure would need to be conveyed either in a human-readable `description` field, or through a mechanism outside of the OpenAPI Description, such as a JSON Schema for the data structure to be queried.

Assuming a path of `/foo` and a server of `https://example.com`, the full URL incorporateing the value from the `example` field would be:

```uri
https://example.com/foo?%24.a.b%5B1%3A1%5D
```

#### Request Body Object

Describes a single request body.
Expand Down
39 changes: 28 additions & 11 deletions src/schemas/validation/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ $defs:
in:
enum:
- query
- querystring
- header
- path
- cookie
Expand All @@ -359,17 +360,33 @@ $defs:
- schema
- required:
- content
if:
properties:
in:
const: query
required:
- in
then:
properties:
allowEmptyValue:
default: false
type: boolean
allOf:
- if:
properties:
in:
const: query
required:
- in
then:
properties:
allowEmptyValue:
default: false
type: boolean
- if:
properties:
in:
const: querystring
required:
- in
then:
required:
- content
not:
required:
- schema
- style
- explode
- allowReserved
dependentSchemas:
schema:
properties:
Expand Down