Skip to content

Pagination

The GoTab GraphQL API uses cursor-based pagination conforming to the Relay Connections spec. Most list queries return a Connection type that includes pagination metadata alongside the data nodes.


Most resources expose two query shapes:

TypeExampleWhen to use
Connectiontabs(first: 25, after: $cursor)Paginating large datasets
ListtabsList(filter: {...})Small, bounded result sets where you need a flat array

Connection queries return nodes (your data) and pageInfo (cursor metadata). List queries return a plain array — no pagination support.


FieldTypeDescription
hasNextPageBooleantrue if more results exist after the current page
hasPreviousPageBooleantrue if results exist before the current page
startCursorStringCursor pointing to the first node in this page
endCursorStringCursor pointing to the last node — pass this as after on the next request

Pass null as the cursor on the first request, then use endCursor from each response as the after variable for the next:

query paginatedTabs($limit: Int, $cursor: Cursor, $createdAfter: Datetime) {
tabs(
first: $limit
after: $cursor
filter: { created: { greaterThanOrEqualTo: $createdAfter } }
) {
nodes {
name
tabUuid
created
}
pageInfo {
endCursor
hasNextPage
}
}
}

First request variables:

{ "limit": 25, "cursor": null, "createdAfter": "2024-01-01" }

Response:

{
"data": {
"tabs": {
"nodes": [ /* 25 tabs */ ],
"pageInfo": {
"endCursor": "WyJwcmltYXJ5X2tleV9hc2MiLFs4NjAyNzMyXV0=",
"hasNextPage": true
}
}
}
}

Next request variables:

{ "limit": 25, "cursor": "WyJwcmltYXJ5X2tleV9hc2MiLFs4NjAyNzMyXV0=", "createdAfter": "2024-01-01" }

Continue until hasNextPage is false.


async function fetchAllTabs(client, createdAfter) {
const query = `
query ($limit: Int, $cursor: Cursor, $createdAfter: Datetime) {
tabs(first: $limit, after: $cursor, filter: { created: { greaterThanOrEqualTo: $createdAfter } }) {
nodes { name tabUuid created }
pageInfo { endCursor hasNextPage }
}
}
`;
const allTabs = [];
let cursor = null;
do {
const { data } = await client.query(query, {
limit: 100,
cursor,
createdAfter,
});
allTabs.push(...data.tabs.nodes);
cursor = data.tabs.pageInfo.endCursor;
} while (data.tabs.pageInfo.hasNextPage);
return allTabs;
}

Use a large limit (up to 100) for bulk exports to minimize round trips.