Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2e25ee9

Browse filesBrowse files
committed
oas: pagination
1 parent 3842a14 commit 2e25ee9
Copy full SHA for 2e25ee9

File tree

Expand file treeCollapse file tree

3 files changed

+325
-10
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+325
-10
lines changed

‎api-design/caching.mdx

Copy file name to clipboardExpand all lines: api-design/caching.mdx
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ In order for a user to pick their seat on the train, there could be a sub-resour
287287
GET /bookings/:my_booking_ref/seating
288288
```
289289

290-
```
290+
```json
291291
{
292292
"my_seat": "A12",
293293
"available_seats": [

‎docs/customize/runtime/pagination.mdx

Copy file name to clipboardExpand all lines: docs/customize/runtime/pagination.mdx
+7-9Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ sidebar_label: "Add Pagination"
44
slug: "/customize-sdks/pagination/"
55
---
66

7-
# Adding Pagination to Your SDK
7+
# Adding pagination to SDKs
88

99
Customize pagination rules for each API operation using the `x-speakeasy-pagination` extension.
1010

@@ -20,9 +20,9 @@ while response is not None:
2020

2121
The `next()` function returns `nil, nil` when there are no more pages to retrieve, indicating the end of pagination rather than an error
2222

23-
## Configuring Pagination
23+
## Configuring pagination
2424

25-
To configure pagination, add the `x-speakeasy-pagination` extension to your OpenAPI specification.
25+
To configure pagination, add the `x-speakeasy-pagination` extension to the OpenAPI description.
2626

2727
```yaml
2828
/paginated/endpoint:
@@ -60,7 +60,7 @@ To configure pagination, add the `x-speakeasy-pagination` extension to your Open
6060
6161
The `x-speakeasy-pagination` configuration supports `offsetLimit`, `cursor`, and `url` implementations of pagination.
6262

63-
### Offset and Limit Pagination
63+
### Offset and limit pagination
6464

6565
For `type: offsetLimit pagination`, specify at least one of the following `inputs`: `offset` or `page`.
6666

@@ -128,9 +128,7 @@ x-speakeasy-pagination:
128128
results: $.data.resultArray # The length of data.resultArray value of the response will be added to the `offset` value to determine the new offset
129129
```
130130
131-
132-
133-
### Cursor-Based Pagination
131+
### Cursor-based pagination
134132
135133
For `type: cursor pagination`, configure the `nextCursor` output.
136134

@@ -171,9 +169,9 @@ At least one response object must have the following structure:
171169

172170
The `[@length-1]` syntax in `outputs.nextCursor` indicates the last value in an array. Ensure the type of `requestBody.since` matches the type of `outputs.nextCursor`.
173171

174-
### URL-Based Pagination
172+
### URL-based pagination
175173

176-
When your API returns a URL for the next page, you can use the `url` type in `x-speakeasy-pagination`. Here's an example configuration:
174+
When an API returns a URL for the next page, you can use the `url` type in `x-speakeasy-pagination`. Here's an example configuration:
177175

178176
```yaml
179177
/paginated/endpoint:

‎openapi/pagination.mdx

Copy file name to clipboard
+317Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
---
2+
title: Pagination
3+
description: Learn how to implement pagination in OpenAPI specifications, including query parameters, headers, and response formats.
4+
---
5+
6+
# Pagination in OpenAPI
7+
8+
Describing a collection of resources in an API may be simple at first, but
9+
certain features like pagination can make it more complex. Pagination is a
10+
common requirement for APIs that return large sets of data, which allows for a
11+
subsection of a collection to be returned (maybe only 20-100 resources) to avoid
12+
overwhelming the server, the client, and all the network components in between.
13+
14+
This is usually implemented as a query parameter, such as `?page=1` or
15+
`?cursor=abc123`, so that a client can request a specific page of results. The
16+
API can then return a subset of the data, and depending on the specific
17+
pagination strategy used there could also be metadata about the total number of
18+
items and the total number of pages. That metadata allows a client to display
19+
pagination controls in the interface such as "Page 1", "Page 2", or simply
20+
"Next" and "Previous" buttons.
21+
22+
You can learn more about various approaches to pagination in the API design guide
23+
[here](https://www.moesif.com/blog/api-design-guide/pagination/).
24+
25+
This guide will show you how to implement pagination in OpenAPI, regardless of
26+
which strategy the API has chosen.
27+
28+
## Pagination with query parameters
29+
30+
Query parameters are a common way to implement pagination in APIs. The most
31+
common query parameters for pagination are `page` and `limit`, which specify the
32+
page number and the number of items per page, respectively.
33+
This is a common approach for paginating through large sets of data, and is
34+
often used in REST APIs.
35+
36+
```yaml
37+
paths:
38+
/stations:
39+
get:
40+
summary: Get a list of train stations
41+
description: Returns a paginated and searchable list of all train stations.
42+
operationId: get-stations
43+
parameters:
44+
- name: page
45+
in: query
46+
description: The page number to return
47+
required: false
48+
schema:
49+
type: integer
50+
minimum: 1
51+
default: 1
52+
example: 1
53+
- name: limit
54+
in: query
55+
description: The number of items to return per page
56+
required: false
57+
schema:
58+
type: integer
59+
minimum: 1
60+
maximum: 100
61+
default: 10
62+
example: 10
63+
```
64+
65+
Adding the `page` and `limit` query parameters advertises to the API consumers
66+
that the API supports pagination. Pagination is mentioned in the description
67+
too, increasing the chance of it being noticed by any API client developers.
68+
69+
The `page` parameter specifies the page number the API should return, and the
70+
optional `limit` parameter specifies the number of items to return for that
71+
page. This is helpful for mobile apps that want to return a grid of data to the
72+
user. For example a 3x3 grid of items, which would require 9 items to be
73+
returned, instead of the default 10 giving the user a blank space in the grid.
74+
75+
## Describing pagination metadata
76+
77+
When implementing pagination, a common practice is to include metadata in the
78+
response to provide information about the total number of items, the current
79+
page, and the total number of pages. This metadata can be included in the
80+
response body, or sometimes is done with custom HTTP headers (which is frowned
81+
upon but done anyway).
82+
83+
Using a `meta` object in an array would not work, so APIs often wrap the
84+
collection with an "envelope" which might be something like `data`.
85+
86+
```json
87+
{
88+
"data": [
89+
...
90+
],
91+
"meta": {
92+
"page": 2,
93+
"size": 10,
94+
"total_pages": 100
95+
}
96+
```
97+
98+
If the API is doing this, the response can be described with the following OpenAPI:
99+
100+
```yaml
101+
responses:
102+
'200':
103+
description: A paginated list of train stations.
104+
content:
105+
application/json:
106+
schema:
107+
type: object
108+
properties:
109+
data:
110+
type: array
111+
items:
112+
$ref: '#/components/schemas/Station'
113+
meta:
114+
type: object
115+
properties:
116+
page:
117+
type: integer
118+
example: 2
119+
size:
120+
type: integer
121+
example: 10
122+
total_pages:
123+
type: integer
124+
example: 100
125+
```
126+
127+
This meta object can be defined in `components` and referenced to avoid repeating it
128+
in every endpoint.
129+
130+
Learn more about components [here](/openapi/components).
131+
132+
## Describing pagination with response links
133+
134+
Adding a query parameter to the API is a good start, but asking API clients to
135+
construct URLs from little bits of data is always confusing and a recipe for
136+
disaster. REST APIs offer the ability to send links which can be used to
137+
crawl the API following links like a browser would.
138+
139+
If the API supports pagination links they
140+
need to be described so clients can use them. The most common way to do this is to
141+
include a `links` object in the response.
142+
143+
```json
144+
{
145+
"data": [
146+
...
147+
],
148+
"links": {
149+
"self": "https://api.example.com/stations?page=2",
150+
"next": "https://api.example.com/stations?page=3",
151+
"prev": "https://api.example.com/stations?page=1"
152+
}
153+
}
154+
```
155+
156+
That links object can be described in OpenAPI like using the following approach:
157+
158+
```yaml
159+
responses:
160+
'200':
161+
description: OK
162+
content:
163+
application/json:
164+
schema:
165+
allOf:
166+
- $ref: '#/components/schemas/Wrapper-Collection'
167+
- properties:
168+
data:
169+
type: array
170+
items:
171+
$ref: '#/components/schemas/Station'
172+
- properties:
173+
links:
174+
allOf:
175+
- $ref: '#/components/schemas/Links-Self'
176+
- $ref: '#/components/schemas/Links-Pagination'
177+
178+
components:
179+
Station:
180+
description: A train station.
181+
type: object
182+
properties:
183+
id:
184+
type: string
185+
format: uuid
186+
description: Unique identifier for the station.
187+
examples:
188+
- efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
189+
- b2e783e1-c824-4d63-b37a-d8d698862f1d
190+
# ... snip ...
191+
Links-Self:
192+
description: The link to the current resource.
193+
type: object
194+
properties:
195+
self:
196+
type: string
197+
format: uri
198+
Links-Pagination:
199+
description: Links to the next and previous pages of a paginated response.
200+
type: object
201+
properties:
202+
next:
203+
type: string
204+
format: uri
205+
prev:
206+
type: string
207+
format: uri
208+
Wrapper-Collection:
209+
type: object
210+
properties:
211+
data:
212+
description: The wrapper for a collection is an array of objects.
213+
type: array
214+
items:
215+
type: object
216+
links:
217+
description: A set of hypermedia links which serve as controls for the client.
218+
type: object
219+
readOnly: true
220+
```
221+
222+
In this example, the `links` object contains three links: `self`, `next`, and
223+
`prev`. The `self` link points to the current page of results, while the `next`
224+
and `prev` links point to the next and previous pages of results, respectively.
225+
The `links` object is described in the OpenAPI specification using the `links`
226+
object, which is a common way to describe hypermedia links in OpenAPI.
227+
228+
## Describing pagination with HTTP headers
229+
230+
Some APIs use custom HTTP headers to provide pagination information instead of trying to wedge the information into the response body and using `data` and `meta`. This has the benefit of keeping the JSON clean and tidy, but can be confusing as there is no standard for pagination headers. The `Link` header is a standard HTTP header that can be used to provide links for general HATEOAS purposes but also for pagination specifically, but it does not have anywhere to pass pagination metadata about numbers of pages.
231+
232+
For example, an API might use something like `X-Total-Count` header to indicate the total number of items in
233+
the collection, and the `X-Page` and `X-Per-Page` headers to indicate the
234+
current page and the number of items per page, then next and previous links in the `Link` header.
235+
236+
```yaml
237+
paths:
238+
/stations:
239+
get:
240+
summary: Get a list of train stations
241+
description: Returns a paginated and searchable list of all train stations.
242+
operationId: get-stations
243+
responses:
244+
'200':
245+
description: A paginated list of train stations.
246+
headers:
247+
X-Total-Count:
248+
description: The total number of items in the collection.
249+
schema:
250+
type: integer
251+
example: 1000
252+
X-Page:
253+
description: The current page number.
254+
schema:
255+
type: integer
256+
example: 2
257+
X-Per-Page:
258+
description: The number of items per page.
259+
schema:
260+
type: integer
261+
example: 10
262+
Links:
263+
description: A set of hypermedia links which serve as controls for the client.
264+
type: string
265+
example: |
266+
<https://api.example.com/stations?page=2>; rel="self",
267+
<https://api.example.com/stations?page=3>; rel="next",
268+
<https://api.example.com/stations?page=1>; rel="prev"
269+
270+
```
271+
272+
However the API is doing pagination, OpenAPI can describe it. The most
273+
important thing is to be consistent and clear about how pagination works in the
274+
API reference documentation, and if possible write a custom guide for explaining pagination in an API more specifically so that API consumers can get it right.
275+
276+
## Speakeasy SDK pagination
277+
Speakeasy SDKs support pagination out of the box, and can be configured to
278+
automatically handle pagination for any API, allowing clients to focus on working with data instead of learning about specific pagination strategies.
279+
280+
To configure pagination, add the `x-speakeasy-pagination` extension to the OpenAPI description:
281+
282+
```yaml
283+
/stations:
284+
get:
285+
parameters:
286+
- name: page
287+
in: query
288+
schema:
289+
type: integer
290+
required: true
291+
responses:
292+
"200":
293+
description: OK
294+
content:
295+
application/json:
296+
schema:
297+
type: object
298+
properties:
299+
data:
300+
type: array
301+
items:
302+
type: integer
303+
required:
304+
- data
305+
x-speakeasy-pagination:
306+
type: offsetLimit
307+
inputs:
308+
- name: page
309+
in: parameters
310+
type: page
311+
outputs:
312+
results: $.data
313+
```
314+
315+
The `x-speakeasy-pagination` configuration supports `offsetLimit`, `cursor`, and `url` implementations of pagination, and allows the generated SDKs to extract the proper response data from the API instead of having to split up data and metadata manually.
316+
317+
Learn more about pagination with Speakeasy SDKs [here](/docs/customize/runtime/pagination).

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.