Many calls to the StackPath API return a list of items. Result sets with large lists may not be performant to process all at once, so StackPath separates the result into smaller sets that are easier to handle. This process is called pagination. API clients should be aware of paginated results to ensure they receive a full data set from StackPath and that their application runs as efficiently as possible.
StackPath employs cursor-based pagination. Unlike systems that return a page number and the number of items per page, paginated StackPath API results contain a result set and a pointer to the next result set called a cursor. This system is very similar to GraphQL's pagination implementation.
Pagination in results
Any call that returns a long list of items may employ pagination. For instance, a list of an account's stacks is a paginate result. The API call:
$ curl --request GET \
--url https://gateway.stackpath.com/stack/v1/stacks \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_BEARER_TOKEN'
Produces a response similar to:
HTTP/1.1 200 OK
Date: Thu, 27 Feb 2020 00:34:28 GMT
Content-Type: application/json
Connection: keep-alive
Vary: Accept-Encoding
Grpc-Metadata-Content-Type: application/grpc
Strict-Transport-Security: max-age=15724800; includeSubDomains
{
"pageInfo": {
"totalCount": "99",
"hasPreviousPage": false,
"hasNextPage": true,
"endCursor": "9"
},
"results": [
{
"id": "74dd3b65-5f01-4b1e-8fcc-ad8443568af7",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "my-default-stack-0c13e2",
"name": "My Default Stack",
"createdAt": "2018-07-02T06:06:42.507271Z",
"updatedAt": "2018-07-02T06:06:42.507271Z",
"status": "ACTIVE"
},
{
"id": "c37047b8-c6f4-4c36-bbe4-974b606f7d37",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "app-production-20181120-2-c05c87",
"name": "App Production",
"createdAt": "2018-11-20T15:38:01.627144Z",
"updatedAt": "2018-11-20T15:56:05.040840Z",
"status": "ACTIVE"
},
{
"id": "19136a80-5d69-408d-829c-ed2570ad5a84",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "app-development-355-9cda0e",
"name": "App Development",
"createdAt": "2018-10-02T16:56:18.491893Z",
"updatedAt": "2018-10-02T17:08:04.625675Z",
"status": "ACTIVE"
},
{
"id": "95e3e84e-cc96-4414-bcb8-ab44d52fc3b0",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "app-qa-29ff1c",
"name": "App QA",
"createdAt": "2019-07-26T17:57:55.721918Z",
"updatedAt": "2019-07-26T18:12:28.697284Z",
"status": "ACTIVE"
},
{
"id": "07e22719-ae1c-4b22-ae29-fe4b1c55842a",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "marketing-b26947",
"name": "Marketing",
"createdAt": "2019-01-24T18:28:06.802980Z",
"updatedAt": "2019-01-24T18:30:39.838348Z",
"status": "ACTIVE"
},
{
"id": "a7ba72a0-e911-4cef-8d45-62dbe5bd9fa9",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "r-d-7d39db",
"name": "R&D",
"createdAt": "2018-10-16T19:11:04.398320Z",
"updatedAt": "2018-10-16T19:43:50.509841Z",
"status": "ACTIVE"
},
{
"id": "0c7ccb9e-603e-44b8-98d6-df64597452fe",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "bobs-test-stack-cab230",
"name": "Bob's Test Stack",
"createdAt": "2019-03-21T15:57:28.178443Z",
"updatedAt": "2019-03-21T15:58:48.825158Z",
"status": "DISABLED"
},
{
"id": "4666a50b-a2db-495f-a228-ce5092af4412",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "alices-test-stack-7ff531",
"name": "Alice's Test Stack",
"createdAt": "2019-09-13T00:18:20.314652Z",
"updatedAt": "2019-09-16T18:32:21.214809Z",
"status": "DISABLED"
},
{
"id": "d39b8165-42e9-4d0b-b5df-bba0f94ec4c2",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "resellers-821fd1",
"name": "Resellers",
"createdAt": "2018-10-19T21:10:04.613637Z",
"updatedAt": "2018-10-19T21:18:00.300770Z",
"status": "ACTIVE"
},
{
"id": "f0c4907c-5c21-4a94-8fef-84ded777aa5b",
"accountId": "6129025b-bbb4-4218-a912-484c990e1c55",
"slug": "internal-services-production-583ff2",
"name": "Internal Services Production",
"createdAt": "2019-02-27T16:37:39.458813Z",
"updatedAt": "2019-02-27T16:40:51.672770Z",
"status": "ACTIVE"
}
]
}
Paginated responses contain two fields:
results
: The current page of requested items. The example above shows stacks, but they could contain compute workloads, custom WAF rules, a list of users, or anything else the StackPath API can return.pageInfo
: Information about the current page of results. It contains the fields:totalCount
: The total number of items in the result sethasPreviousPage
: Whether there are items in the result set before the current page of resultshasNextPage
: Whether there are items in the result set after the current page of resultsstartCursor
: The cursor to the beginning of the results. This is not present on the first page of resultsendCursor
: The cursor to the next page of results. This value equals thetotalCount
value when retrieving the end of a result set
Use the endCursor
value to request other pages of results. endCursor
's format varies depending on the kind of data requested. It may be a result row number, but sometimes it can refer to the ID of the next item in the result set.
Requesting pagination
Request pages of data by adding pagination parameters to your API call URL's query string. StackPath supports two variables to control pagination:
page_request.first
: The number of items to retrieve in the page. Default page sizes vary depending on the data being retrievedpage_request.after
: The value of the cursor to retrieve results after. This value defaults to zero if it's not provided, retrieving items from the beginning of the result set
Requesting pagination from StackPath completes the sentence: "Give me the first page_request.first items starting after item page_request.after."
For instance, the URL to retrieve a second page of stacks is https://gateway.stackpath.com/stack/v1/stacks?page_request.after=9 since the pageInfo.endCursor
value from the previous call is 9:
$ curl --request GET \
--url 'https://gateway.stackpath.com/stack/v1/stacks?page_request.after=9' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_BEARER_TOKEN'
The response to this call contains a startCursor
in addition to an endCursor
. Both hasPreviousPage
and hasNextPage
are true, meaning that these results are in the middle of the full result set.
HTTP/1.1 200 OK
Date: Wed, 15 Apr 2020 20:58:42 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15724800; includeSubDomains
Grpc-Metadata-Content-Type: application/grpc
{
"pageInfo": {
"totalCount": "99",
"hasPreviousPage": true,
"hasNextPage": true,
"startCursor": "10",
"endCursor": "19"
},
"results": [
// The second page of stacks
]
}
Requesting all pages
Use the pageInfo.hasNextPage
and pageInfo.endCursor
result fields in a loop to retrieve a full set of paginated results. Consider the following pseudocode:
// Start with defaults to retrieve the first page of results
hasNextPage = true
cursor = 0
// Store stacks here
stacks = []
while hasNextPage {
// How to call the StackPath API depends on your platform
response = callStackPath(
"https://gateway.stackpath.com/stack/v1/stacks?page_request.after=" + cursor
)
// Add the returned stacks to the full result
stacks = append(stacks, response.results);
// Prepare for the next page of API calls
cursor = response.pageInfo.endCursor
// See if there are more stacks to retrieve
hasNextPage = response.pageInfo.hasNextPage
}
Updated 2 days ago