Pagination/Continuation

Pagination/Continuation

Pagination/Continuation

Pagination (sometimes called “continuation”) allows lists of items to be retrieved in subsets called “pages”. APIs that support the retrieval of large quantities of resources MUST implement pagination. APIs that return relatively small-sized lists (e.g. a list of days of the week) MAY choose not to.

Pagination Types

Trimble APIs use either offset-based pagination or cursor-based pagination.

Offset-Based Pagination

Most APIs that return collections allow the caller to get a specific page of results. This is accomplished by including the URL parameter “pageIndex” in the request.

Subsequent pages of results from these APIs may be retrieved by forming URLs with an incrementing pageIndex value in the URL or by performing a GET to the URL for next returned in the links block (see Common Pagination Information and Contract below).

APIs implementing offset-based pagination MUST support the following query parameters on collection requests that support a GET operation:

FieldPurposeDefaultNotes
pageIndexIdentifies the index of the requested page.

This is essentially the “page number” with the numbering starting at 0.
0 (first page)Zero-based integer. Optional.
pageSizeThe largest quantity of items to be returned in a single response (in a single page).100Integer. Optional.

If 0, the API returns an empty items[] array. This is used, for example, when a caller simply wants to know the number of items in a collection that is returned in the metadata of the response.

APIs MUST NOT return less than this quantity of items unless it is the last page.

Example:

GET https://api.trimble.com/service/things?pageIndex=3&pageSize=20

With the default behavior,

GET https://api.trimble.com/service/things

will return the same result as:

GET https://api.trimble.com/service/things?pageIndex=0&pageSize=100

APIs that use offset-based pagination MUST return an array of items along with metadata that contains the page index (zero-based), the total quantity of items in the entire result set and links to get the next page, etc. as follows:

FieldDescriptionNotesRequired
pageIndexindex of the returned pageIntegerRequired
totalItemstotal number of items in the entire query result, across all pagesIntegerRequired
itemsThe data items returned in this specific pageJSON array of JSON objects.

If a query results in no items, this is an empty JSON array.
Required
linksSee Common Pagination Information and Contract below.Required

Example Request:

GET https://api.trimble.com/service/things?pageIndex=1

Example Response:

{
"pageIndex": 1,
"totalItems": 119,
"items": [
{...},
{...},
...
],
"links": "(see Common Pagination Information and Contract below)."
{...}
}

Cursor-Based Pagination

APIs implementing cursor-based pagination do not accept any parameters regarding specific pages. The initial call always returns the first page of results.

Subsequent pages of results from these APIs may be retrieved by performing a GET to the URL for “next” returned in the “links” block (see Common Pagination Information and Contract below).

APIs Implementing cursor-based pagination MUST have data that enable a stable sort to ensure consistent responses to queries.

APIs implementing cursor-based pagination MUST support the following query parameters on collection requests supporting a GET operation:

FieldPurposeDefaultNotes
pageSizeThe largest quantity of items to be returned in a single response (in a single page).100Integer. Optional.

Note this can be 0 in which case the API returns an empty items[] array. This is used, for example, when a caller simply wants to know the quantity of items in a collection which is returned in the metadata of the response.

Note that APIs MUST NOT return less than this quantity of items unless it is the last page.

Example:

GET https://api.trimble.com/service/things?pageSize=20

APIs implementing cursor-based pagination MUST return an array of items and metadata that contains the total quantity of items in the entire result set and links to get the next page, etc. as follows:

FieldPurposeNotesRequired
totalItemsTotal number of items in the entire query result, across all pagesInteger.

This may not be present when the result set is quickly changing or the item count is unknown or complex to calculate.
Optional
itemsThe data elements returned on this specific pageJSON array of JSON objects

If a query results in no items, this is an empty JSON array.
Required
linksSee Common Pagination Information and Contract below.Required

Example Request:

GET https://api.trimble.com/service/things

Example Response:

{
"totalItems": 19,
"items": [
{...},
{...},
...
],
"links": "(see Common Pagination Information and Contract below)."
{...}
}

Common Pagination/Continuation Information & Contract (Both Paging Types)

Both paging types (offset and cursor) share and MUST include a common response block, links, that contains URLs that can be used to retrieve next and previous pages (and several other navigation URLs). The following are the navigation URLs supported, with the conditions in which they are required:

FieldPurposeNotes
selfA URL that will retrieve the response that was just received.Required. This URL may not exactly match the URL provided by the caller but will return the same result.
firstA URL that will retrieve the first page of results.Required. There is always a first page - even if it is empty.
nextA URL that will retrieve the next page of results.Required if there is a next page. Omitted if no pages follow this page.
prevA URL that will retrieve the previous page of results.Required if there is a previous page. Omitted if no pages precede this page.
lastA URL that will retrieve the last page of results.Required if there is a known last page. Omitted if the “last page” is unknown or too complex to calculate (as in a very rapidly growing collection)

APIs MUST return complete URLs to fetch next and previous pages regardless of the pagination type. This removes the need for the caller to know which type of paging is in use in most cases.

Below is an example response from an API containing navigation information.

{
"pageIndex": 3, // (may not be present for APIs that use cursor-based continuation only)
"totalItems": 1960, // (may not be present for APIs that use cursor-based continuation only)
"items": [
{ ... },
{ ... },
...
],
"links": {
"self": {
"href": "https://api.trimble.com/service/users?pageSize=100&pageIndex=3"
},
"first": {
"href": "https://api.trimble.com/service/users?pageSize=100"
},
"prev": {
"href": "https://api.trimble.com/service/users?pageSize=100&pageIndex=2"
},
"next": {
"href": "https://api.trimble.com/service/users?pageSize=100&pageIndex=4"
},
"last": {
"href": "https://api.trimble.com/service/users?pageSize=100&pageIndex=19"
}
}
}

The URLs in the links block should not be parsed by client-side developers as their content and/or format may change without notice. These URLs are intended to be used in GET calls as-is without interpretation or modification.

The table below describes the differences between the 2 paging methods:

Offset-Based PaginationCursor-Based Pagination
Collection size changes slowly.
Size can be known in advance.

Example: A list of employees
Collection size changes rapidly.
Its size is unknown or impractical to calculate.

Example: An ever-increasing list of events
Access any specific pageONLY sequential access to pages
URL Query Parameters
pageIndex=YesNo
pageSize=YesYes
Returned Navigation Links
links.nextYesYes
links.prevYesYes
links.firstYesYes
links.lastYesMaybe
links.selfYesYes