You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/_guides/openapi/specification/v3.2/advanced/json-streaming.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -348,4 +348,5 @@ Whatever the schema is, it can be defined using the standard JSON Schema keyword
348
348
349
349
## Further Reading
350
350
351
-
You can find details in the **OpenAPI Specification v3.2.0** under [Media Types Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.2.0.md#media-type-object) and look for `itemSchema`.
351
+
- [Learn OpenAPI: Sequential Media Types](https://learn.openapis.org/specification/media-types.html)
352
+
- [OpenAPI Specification v3.2.0: Media Types Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.2.0.md#media-type-object)
Copy file name to clipboardExpand all lines: src/_guides/openapi/specification/v3.2/understanding-structure/http-requests.md
+110-4Lines changed: 110 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,12 +8,27 @@ date: 2025-07-09
8
8
- TOC
9
9
{:toc}
10
10
11
-
Any API handling use-cases more advanced that purely fetching data will need to define a HTTP request body. `POST`, `PATCH`, `PUT`, `QUERY`, etc. all allow a HTTP client to send a body: often JSON or XML. This allows for more information to be sent rather than just query string parameters, which have limits.
11
+
HTTP requests are a fundamental part of any API. They allow clients to send data to the server, whether that’s creating new resources, updating existing ones, or performing complex queries.
12
12
13
-
The request body can be used for:
13
+
OpenAPI 3.x provides a robust way to define these requests, and OpenAPI v3.2 introduces even more capabilities to handle a wider range of scenarios.
14
+
15
+
Supported HTTP Methods:
16
+
17
+
-`GET`
18
+
-`PATCH`
19
+
-`POST`
20
+
-`PUT`
21
+
-`DELETE`
22
+
-`HEAD`
23
+
-`OPTIONS`
24
+
-`TRACE`
25
+
-`QUERY`
26
+
- Additional custom methods via `additionalOperations`
27
+
28
+
The HTTP request can also include a body: usually JSON or XML. The request body can be used for:
14
29
15
30
- Creating new resources (e.g.: booking a train ticket)
16
-
- Updating existing resources (e.g.: updating that booking)
31
+
- Updating existing resources (e.g.: updating or cancelling that booking)
17
32
- Uploading files (e.g.: uploading an image to your railcard)
18
33
19
34
## Structure of Request Bodies
@@ -63,7 +78,6 @@ paths:
63
78
Here the `requestBody` object defines two important properties:
64
79
65
80
- `required: true` - indicates that the request body is mandatory for this operation.
66
-
67
81
- `content`- specifies that the request body should be in `application/json` format with the following `schema`.
68
82
69
83
The schema defines the structure of the request body, including properties like `passenger_name`, `train_id`, `date`, and `seat_preference`. This can be defined inline like this, or it can use `components` to share an [existing schema](_guides/openapi/specification/v3.2/data-models/schema-and-data-types.md) and reduce repetition.
@@ -104,6 +118,98 @@ The `schema` then defines the structure of the request body, which demonstrates
104
118
105
119
If multiple properties could be updated, you would define all the properties that could be updated, then show off some [examples](_guides/openapi/specification/v3.2/data-models/examples.md) for common use-cases of things users might want to do.
106
120
121
+
## Query Requests
122
+
123
+
OpenAPI 3.2 adds native support for the `QUERY` HTTP method, which is designed to support complex queries that don’t fit neatly in URL query strings.
124
+
125
+
Prior to the HTTP Query method it was common for people to add infinite query string parameters like `?origin=london&destination=paris&has_dogs=true`, or to try and create some sort of query syntax using a standard or home-grown DSL like `?filter=origin:london,destination:paris,has_dogs:true`, but these syntaxes struggle when it comes to `is null`, `not null`, or `>=10`. Putting the query into the body allows for more advanced structures using JSON for example.
126
+
127
+
```yaml
128
+
paths:
129
+
/products:
130
+
query:
131
+
summary: Product search
132
+
requestBody:
133
+
required: true
134
+
content:
135
+
application/json:
136
+
schema:
137
+
type: object
138
+
properties:
139
+
filter:
140
+
type: object
141
+
required: [field, value]
142
+
properties:
143
+
field:
144
+
type: string
145
+
examples: [id]
146
+
value:
147
+
type: string
148
+
examples: [abc123]
149
+
operator:
150
+
type: string
151
+
example: "!="
152
+
sort:
153
+
type: array
154
+
items:
155
+
type: string
156
+
responses:
157
+
'200':
158
+
description: Search results
159
+
```
160
+
161
+
Within a simple structure like this, searching and filtering can be handled with a more useful
162
+
163
+
```http
164
+
QUERY /feed
165
+
Content-Type: application/json
166
+
167
+
{
168
+
"q": "foo",
169
+
"limit": 10,
170
+
"sort": "-published",
171
+
"filter": [
172
+
{
173
+
"field": "origin",
174
+
"value": "london"
175
+
},
176
+
{
177
+
"field": "destination",
178
+
"value": "paris"
179
+
},
180
+
{
181
+
"field": "price",
182
+
"value": "60.00",
183
+
"operator": "<="
184
+
}
185
+
}
186
+
```
187
+
188
+
## Additional HTTP Methods
189
+
190
+
Use `additionalOperations` for HTTP methods not covered by standard OpenAPI operations.
191
+
192
+
For example, maybe an API is using the `PURGE` HTTP method to remove cached resources from the an API behind a cache proxy like [Varnish](https://varnish-cache.org/docs/3.0/tutorial/purging.html).
193
+
194
+
```yaml
195
+
paths:
196
+
/tickets/{ticketId}:
197
+
parameters:
198
+
- name: ticketId
199
+
in: path
200
+
required: true
201
+
schema:
202
+
type: string
203
+
additionalOperations:
204
+
PURGE:
205
+
summary: Purge a ticket from the cache
206
+
responses:
207
+
'204':
208
+
description: Ticket purged from cache
209
+
```
210
+
211
+
This allows for full support of any HTTP method you can think of, allowing OpenAPI v3.2 to go beyond only supporting the core HTTP methods.
212
+
107
213
## File Uploads & Multipart Forms
108
214
109
215
HTTP requests can also cover more advanced scenarios like [file uploads](_guides/openapi/specification/v3.2/advanced/file-uploads.md) and [multipart form data](_guides/openapi/specification/v3.2/advanced/multipart-form-data.md), which have their own guides in the advanced section.
Copy file name to clipboardExpand all lines: src/_guides/openapi/specification/v3.2/understanding-structure/parameter-serialization.md
+15-9Lines changed: 15 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ date: 2024-07-04
8
8
- TOC
9
9
{:toc}
10
10
11
-
[Parameters](_guides/openapi/specification/v3.2/understanding-structure/parameters.md) not only define what inputs your API accepts, they also define the format your API expects to receive them in, i.e. how you would like it serialized.
11
+
[Parameters](_guides/openapi/specification/v3.2/understanding-structure/parameters.md) not only define what inputs your API accepts, they also define the format your API expects to receive them in, i.e. how those parameters should serialized.
12
12
13
13
There are two keywords concerning serialization:
14
14
@@ -199,9 +199,9 @@ This conflict is entirely avoided if you explicitly set `explode:false` on param
199
199
200
200
It's basically identical to `style:form` with `explode:false`. The difference being, the separator used is not a comma, but a percent-encoded space "%20".
201
201
202
-
You'll notice there are no examples for any `type` that would be a single value. This is because its behaviour is undefined for single values. One could assume it would be identical to `style:form`, but if your parameter is going to be a single value, there is no need to explicitly define it as `spaceDelimited`.
202
+
You'll notice there are no examples for any `type` that would be a single value. This is because its behavior is undefined for single values. One could assume it would be identical to `style:form`, but if your parameter is going to be a single value, there is no need to explicitly define it as `spaceDelimited`.
203
203
204
-
`style:spaceDelimited` is not defined by [RFC6750](https://datatracker.ietf.org/doc/html/rfc6750) and there is no defined behaviour for `explode:true`. You could assume it would be identical to the well-defined `in:query` default of `style:form` with `explode:true`. That said, if you're making that assumption, you're better off leaving it on the well-defined default.
204
+
`style:spaceDelimited` is not defined by [RFC6750](https://datatracker.ietf.org/doc/html/rfc6750) and there is no defined behavior for `explode:true`. You could assume it would be identical to the well-defined `in:query` default of `style:form` with `explode:true`. That said, if you're making that assumption, you're better off leaving it on the well-defined default.
205
205
206
206
### Pipe Delimited
207
207
@@ -222,13 +222,13 @@ If you still choose to use non-percent-encoded pipes, it would look like this:
You'll notice there are no examples for any `type` that would be a single value. This is because its behaviour is undefined for single values. One could assume it would be identical to `style:form`, but if your parameter is going to be a single value, there is no need to explicitly define it as `spaceDelimited`.
225
+
You'll notice there are no examples for any `type` that would be a single value. This is because its behavior is undefined for single values. One could assume it would be identical to `style:form`, but if your parameter is going to be a single value, there is no need to explicitly define it as `spaceDelimited`.
226
226
227
-
`style:pipeDelimited` is not defined by [RFC6750](https://datatracker.ietf.org/doc/html/rfc6750) and there is no defined behaviour for `explode:true`. You could assume it would be identical to the well-defined `in:query` default of `style:form` with `explode:true`. That said, if you're making that assumption, you're better off leaving it on the well-defined default.
227
+
`style:pipeDelimited` is not defined by [RFC6750](https://datatracker.ietf.org/doc/html/rfc6750) and there is no defined behavior for `explode:true`. You could assume it would be identical to the well-defined `in:query` default of `style:form` with `explode:true`. That said, if you're making that assumption, you're better off leaving it on the well-defined default.
228
228
229
229
### Deep Object
230
230
231
-
`style:deepObject` is undefined for its default of `explode:false`. You must explicitly specify `explode:true` for any defined behaviour.
231
+
`style:deepObject` is undefined for its default of `explode:false`. You must explicitly specify `explode:true` for any defined behavior.
232
232
233
233
You may be able to use a normal square brackets "[" and "]" but they are in the list of [RFC3986's Reserved Characters](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2). As such, it may not work in some environments.
234
234
@@ -246,9 +246,9 @@ For maximum interoperability it is safer to have them percent-encoded:
Unsurprisingly, it only has defined behaviour for an `object`. This `style` is quite different from any other, even with `explode:true` the `name`, key and value are all specified. This makes it useful for avoiding the potential name conflicts objects could cause with `style:form`, `explode:true`.
249
+
Unsurprisingly, it only has defined behavior for an `object`. This `style` is quite different from any other, even with `explode:true` the `name`, key and value are all specified. This makes it useful for avoiding the potential name conflicts objects could cause with `style:form`, `explode:true`.
250
250
251
-
Just bear in mind the name is misleading, despite being called a `deepObject`, there is no defined behaviour for nested arrays or objects. This is the same for every `style``in:query`.
251
+
Just bear in mind the name is misleading, despite being called a `deepObject`, there is no defined behavior for nested arrays or objects. This is the same for every `style``in:query`.
252
252
253
253
## Header Parameters
254
254
@@ -428,8 +428,14 @@ Now our URL will look like this:
428
428
Here I've stated that my `schema` can be `anyOf` the following: an object or a string, in `style:deepObject`. You may have spotted the problem already:
429
429
430
430
- If our user specifies an object, this works as expected: `/trips?station[preferred]=gatwick&station[fallback]=london`.
431
-
- What if our user specifies a string? It's undefined, `deepObject` only has defined behaviour for objects.
431
+
- What if our user specifies a string? It's undefined, `deepObject` only has defined behavior for objects.
432
432
433
433
You cannot apply `style` on a per-`schema` basis. Your `style` needs to work for all possible variations of your parameter.
434
434
If you intend to use `anyOf`, `allOf` or `oneOf` make doubly sure your choice of `style` works for every option.
435
435
As always, the best option is to minimise your use of complex parameters, keep it simple.
436
+
437
+
### Switching DeepObject to Querystring Parameters
438
+
439
+
In OpenAPI v3.2, a new parameter location was added: `in: querystring`to help avoid complexity in `deepObject` parameters. Instead of trying to fit everything into a single parameter, you can now define multiple parameters in the querystring using the same `schema`, which can even have different content types.
440
+
441
+
**Learn more about [Querystring Parameters](_guides/openapi/specification/v3.2/understanding-structure/parameters.md#querystring-parameters).**
Copy file name to clipboardExpand all lines: src/_guides/openapi/specification/v3.2/understanding-structure/parameters.md
+76-3Lines changed: 76 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,13 +17,21 @@ Parameters fall into one of a few types:
17
17
-**Header Parameters:** Included in the request header, e.g., `Acme-Custom-Header: Value`.
18
18
-**Cookie Parameters:** Passed in the request cookies.
19
19
20
-
> In previous versions of OpenAPI the entire request body and form data would all be sent as parameters, but since OpenAPI v3.0 this has been moved to the content object. Learn more in [HTTP Requests](_guides/openapi/specification/v3.2/understanding-structure/http-requests.md).
21
-
{: .info }
22
-
23
20
Each parameter in OpenAPI is defined with specific attributes such as `name`, `in` (location), `required`, `description`, and `schema` (for defining data types and validation rules). Defining parameters with these keywords allows documentation to show example how HTTP requests should be constructed making life easier for the client, but also make sure machines know what to do with it, making SDKs and server-side validation a whole lot more powerful.
24
21
22
+
25
23
## Parameter Types
26
24
25
+
There are four main types of parameters in OpenAPI v3.1, each serving a different purpose in the context of an HTTP request.
26
+
27
+
- Path Parameters - `in: path`
28
+
- Query Parameters -`in: query`
29
+
- Header Parameters - `in: header`
30
+
- Cookie Parameters - `in: cookie`
31
+
- OpenAPI 3.2 also added Querystring Parameters `in: querystring`
32
+
33
+
That new addition is a little confusing as the names are so similar, but we'll cover that in a bit.
34
+
27
35
### Path Parameters
28
36
29
37
The first type of parameter to get the hang of is path parameters.
@@ -154,6 +162,71 @@ paths:
154
162
example: 5
155
163
```
156
164
165
+
### Querystring Parameters
166
+
167
+
OpenAPI v3.2 added support for a new type of parameter called `querystring` parameters. These are similar to query parameters, but they allow for more complex structures to be sent in the query string.
168
+
169
+
Unlike `in: query`, with `in: querystring` the entire query string is treated as a single parameter with complex structure. This means that combinations of query parameters can be expressed using a well-defined Schema object:
170
+
171
+
```yaml
172
+
paths:
173
+
/search:
174
+
get:
175
+
parameters:
176
+
- name: advancedQuery
177
+
in: querystring
178
+
content:
179
+
application/x-www-form-urlencoded:
180
+
schema:
181
+
type: object
182
+
properties:
183
+
filters:
184
+
type: object
185
+
sorting:
186
+
type: array
187
+
items:
188
+
type: string
189
+
```
190
+
191
+
In HTTP that would look like this:
192
+
193
+
```http
194
+
GET /search?filters[origin]=london&filters[destination]=paris&filters[has_dogs]=true&sorting[]=price&sorting[]=duration
195
+
```
196
+
197
+
It also allows for JSON encoded query strings:
198
+
199
+
```yaml
200
+
paths:
201
+
/search:
202
+
get:
203
+
summary: Search for items
204
+
parameters:
205
+
- name: filter
206
+
in: querystring
207
+
content:
208
+
application/json:
209
+
schema:
210
+
type: object
211
+
properties:
212
+
origin:
213
+
type: string
214
+
destination:
215
+
type: string
216
+
has_dogs:
217
+
type: boolean
218
+
219
+
```
220
+
221
+
In HTTP that would look like this:
222
+
223
+
```http
224
+
GET /search?filter={"origin":"london","destination":"paris","has_dogs":true}
225
+
```
226
+
227
+
Handling advanced query strings like this used to rely on trickery with a combination of [parameter serialization](_guides/openapi/specification/v3.2/understanding-structure/parameter-serialization.md) options most users (and tooling) seemed to struggle with. This new `querystring` parameter type makes it much clearer what is going on, and allows for more complex structures to be expressed in a way that is easier to understand.
228
+
229
+
Thanks to this new approach giving you the full power of the `schema` keyword, you can re-use and combine sets of query parameters with allOf, you can make them conditional and interdependent with `if`/`then`/`else`, and support [polymorphism with `oneOf`/`anyOf`](_guides/openapi/specification/v3.2/data-models/schema-composition.md). You can even forbid unexpected parameters with `additionalProperties: false` if you want to be strict about what is allowed.
0 commit comments