Adding pagination to Your SDK
In SDKs managed by Speakeasy, you can customize pagination rules for each API operation using the x-speakeasy-pagination
OpenAPI extension.
Adding pagination to your SDK improves your SDK users' developer experience. If your API is paginated, Speakeasy provides an iterable object that users can loop over. For end users, this means an experience that resembles the following:
response = sdk.paginatedEndpoint(page=1)
while response is not None:
# handle response
response = response.next()
Note: The next()
function returns nil, nil
when the pages are exhausted to differentiate from an error case.
Configuring Pagination
/paginated/endpoint:
get:
parameters:
- name: page
in: query
schema:
type: integer
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
title: res
type: object
properties:
resultArray:
type: array
items:
type: integer
required:
- resultArray
x-speakeasy-pagination:
type: offsetLimit
inputs:
- name: page
in: parameters
type: page
outputs:
results: $.resultArray
The x-speakeasy-pagination
configuration supports both offsetLimit
and cursor
implementations of pagination.
Offset and Limit Pagination
When you specify type: offsetLimit
in the pagination configuration, you need to configure at least one of the following inputs: offset
or page
.
Example inputs.page
Configurations
x-speakeasy-pagination:
type: offsetLimit
inputs:
- name: page # This input refers to the value called `page`
in: parameters # In this case, page is an operation parameter (header, query, or path)
type: page # The page parameter will be used as the page-value for pagination, and will be incremented when `next()` is called
- name: limit # This input refers to the value called `limit`
in: parameters # In this case, limit is an operation parameter (header, query, or path)
type: limit # The limit parameter will be used as the limit-value for pagination
outputs:
results: $.data.resultArray # The data.resultsArray value of the response will be used to infer whether there is another page
In this example, at least one response object must have the following structure:
{
"data": {
"resultArray": []
}
}
Because inputs.limit
is defined in the pagination configuration above, next()
will return null
when $.data.resultArray
has a length less than the value provided as inputs.limit
. If inputs.limit
is omitted, next()
will return null
when the length of $.data.resultArray
is equal to 0
.
If you use the page
input, you can use output.numPages
instead of output.results
to determine when the pages for the operation are exhausted.
x-speakeasy-pagination:
type: offsetLimit
inputs:
- name: page # This input refers to the value called `page`
in: parameters # In this case, page is an operation parameter (header, query, or path)
type: page # The page parameter will be used as the page, and will be incremented when `next()` is called
outputs:
numPages: $.data.numPages # The data.numPages value of the response will be used to infer whether there is another page
If you provide the numPages
output, next()
returns null
when the incremented page number is greater than the numPages
value.
In the above example, at least one response object must have the following structure:
{
"data": {
"numPages": 1
}
}
Example inputs.offset
Configuration
x-speakeasy-pagination:
type: offsetLimit
inputs:
- name: offset # This offset refers to the value called `offset`
in: parameters # In this case, offset is an operation parameter (header, query, or path)
type: offset # The offset parameter will be used as the offset, which will be incremented by the length of the `output.results` array
outputs:
results: $.data.resultArray # The length of data.resultsArray value of the response will be added to the `offset` value to determine the new offset
Note: In this example, inputs.limit
has the same effect as in the inputs.page
example.
Cursor-Based Pagination
When you specify type: cursor
in the pagination configuration, you need to configure the nextCursor
output.
Example inputs.cursor
Configuration
x-speakeasy-pagination:
type: cursor
inputs:
- name: since
in: requestBody
type: cursor
outputs:
nextCursor: $.data.resultArray[(@length-1)].created_at
Because the input above is in
the requestBody
, this operation must take a request body with at least the following structure:
{
"since": ""
}
In the above example, at least one response object must have the following structure:
{
"data": {
"resultArray": [
{
"created_at": ""
}
]
}
}
Note: The [@length-1)]
syntax in outputs.nextCursor
indicates the last value in an array.
Note: The type of requestBody.since
must correspond to the type of outputs.nextCursor
.
Inputs
name
With in: parameters
, this is the name of the parameter to use as the input value.
With in: requestBody
, this is the name of the request-body property to use as the input value.
in
Indicates whether the input should be passed into the operation as a path or query parameter (in: parameters
) or in the request-body (in: requestBody
). Only simple objects are permitted as values in the request-body.
type
Type | Description |
---|---|
page | The variable that will be incremented on calling next() . |
offset | The variable that will be incremented by the number of results returned by the previous execution. Note: Requires outputs.Results . |
limit | When provided, next() returns null (or equivalent) when the number of results returned by the previous execution is less than the value provided. |
Outputs
All of the outputs are expected to be strings adhering to the JSONPath (opens in a new tab) schema.
Key | Description |
---|---|
numPages | When provided, next() returns null if the page input value exceeds the value found at the provided JSON path. Note: Requires page input. |
results | When provided, next() returns null if the array found at the provided JSON path is empty. Note: Required by offset input. |
nextCursor | Populates cursor with the value found at the provided JSON path when calling next() . Note: Required by type: cursor . |
Note: If the JSONPath value provided for an output does not match the response returned, next()
returns null
because pagination cannot be continued.