Skip to main content

Pagination

Edges and nodes

Pagination of results requires queries to be sent via path field edges.

When receiving large amounts of data, it can be a problem to display it in a user-friendly way. The GraphQL API provides flexible options for page-by-page output of data, for which a number of fields and arguments are used.


Cursor

For easy identification of objects in the response, each object has its own identifier called cursor. To get this identifier, the cursor field must be added to the body of the operation:

Request example
{
instruments {
edges {
cursor
node {
basicInformation {
...
}
}
}
}
}

The system will return for cursor the identifier of the selected object in the system database:

Response example
{
"data": {
"instruments": {
"edges": [
{
"cursor": "MA==",
"node": {
"basicInformation": {
...
}
}
},
]
}
}
}

Cursor as a starting point

Received cursor can be used as a starting point for forming the results page. To do this, use the arguments of the root field of the path, with the received cursor as the value:

  • before — objects coming before the specified cursor in the list
  • after — objects following in the list after the specified cursor
Page size

Without specifying the number of objects to return with using the first or last arguments, the system will only return the next 10 records.

Response example
{
instruments(first: 10, after: "MA==") {
edges {
cursor
node {
basicInformation {
...
}
}
}
}
}
caution

The cursor specified in before/after is not included in the selection on the displayed page.


Page navigation

Data of PageInfo type are used for sequential navigation through pages:

  • hasNextPage — whether the next page exists in the given conditions (data format Boolean)
  • hasPreviousPage — whether the previous page exists in the given conditions (data format Boolean)
  • startCursor — the first cursor on the displayed page (data format String)
  • endCursor — the last cursor on the displayed page (data format String)

The PageInfo field is structurally subordinate directly to the root field of the operation, and as such should be placed at the same level as edges, not inside of it:

Request example
{
instruments(first: 5, after: "MjQ=") {
edges {
cursor
node {
basicInformation {
...
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
Response example
{
"data": {
"instruments": {
"edges": [
{
"cursor": "MjU=",
"node": {
"basicInformation": {
...
}
}
},
{
"cursor": "MjY=",
"node": {
"basicInformation": {
...
}
}
},
{
"cursor": "Mjc=",
"node": {
"basicInformation": {
...
}
}
},
{
"cursor": "Mjg=",
"node": {
"basicInformation": {
...
}
}
},
{
"cursor": "Mjk=",
"node": {
"basicInformation": {
...
}
}
}
],
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": true,
"startCursor": "MjU=",
"endCursor": "Mjk="
}
}
}
}

Total object count

The totalCount, which is located at the same level as edge and pageInfo, allows to calculate the total number of records in the system database:

Request example
{
instruments(first: 5, after: "MjQ=") {
edges {
cursor
node {
basicInformation {
...
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}
Response example
{
"data": {
"instruments": {
"edges": [
...
],
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": true,
"startCursor": "MjU=",
"endCursor": "Mjk="
},
"totalCount": 41357
}
}
}

So, the startCursor/endCursor received in the response can be used as the new value of the before/after argument, the hasNextPage/hasPreviousPage value allows you to decide if movement in a given direction is possible, and the total number of objects from totalCount allows you to create a list of pages for easier navigation.


What's next?

Additionally, we recommend reading the following related articles: