diff --git a/src/oas.md b/src/oas.md index 9151acac30..4808af580c 100644 --- a/src/oas.md +++ b/src/oas.md @@ -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. @@ -921,8 +922,8 @@ These fields MAY be used with either `content` or `schema`. | Field Name | Type | Description | | ---- | :----: | ---- | -| name | `string` | **REQUIRED**. The name of the parameter. Parameter names are _case sensitive_. | -| in | `string` | **REQUIRED**. The location of the parameter. Possible values are `"query"`, `"header"`, `"path"` or `"cookie"`. | +| name | `string` | **REQUIRED**. The name of the parameter. Parameter names are _case sensitive_. | +| in | `string` | **REQUIRED**. The location of the parameter. Possible values are `"query"`, `"querystring"`, `"header"`, `"path"` or `"cookie"`. | | 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. | | 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`. | | deprecated | `boolean` | Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is `false`. | @@ -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 | @@ -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 | | ---- | :----: | ---- | | 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. | @@ -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_ | ?color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150 | +##### 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: @@ -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. diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml index a963aedc2d..a2df957cf3 100644 --- a/src/schemas/validation/schema.yaml +++ b/src/schemas/validation/schema.yaml @@ -334,6 +334,7 @@ $defs: in: enum: - query + - querystring - header - path - cookie @@ -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: