Paginated Results
Most of our fields are paginated (you can tell because they will be of a Connection type and will have arguments such as first, last and return fields totalCount, pageInfo etc.
Note that by default anything paginated will return a maximum of 50 results unless otherwise noted in the docs - if you want to return something different you will need to supply pagination arguments (up to the maximum). This also means with no arguments, you will not get all of the results if there are more than 50.
GraphQL pagination: Index or Cursor?
A common use case in GraphQL is to traverse relationships between sets of objects. These relationships are called connections and the simplest way to expose a connection between 2 objects is with a field that returns a plural type. Imagine if we wanted to query for all Products inside a given account:
{
products {
skuCode
}
}
We can quickly see how limited this model may be especially if somebody only needs to fetch 2 or N amount of those products. So we'd need something like:
{
products(first: 2) {
skuCode
}
}
Index-based Pagination
There are plenty of use cases where you need to fetch the next 2 products, and so on, and so on. For that we could do:
- Either
products(first: 2, page: 2) - Or
products(first: 2, offset: 2) - or even
products(first: 2, after: $productID)
We would be implementing an index-based pagination.
Cursor-based Pagination
The second type of pagination available to us is to specify products(first: 2, after: $productCursor)
We're implementing a cursor-based pagination in this case. It's this cursor-based pagination that Zencargo has implemented.
We've found cursor-based pagination to be more powerful and flexible. When cursors are opaque, either offset or ID based pagination can be implemented using cursors. Using cursors gives also flexibility if pagination model changes in the future.
Where to find the Cursor
The cursor is accessible in the return values of operations. You may see return types that are a _*Connection rather than a single Object. For instance, If you look at the Query Root definition for Products, which is what we were alluding to above, the return value is ProductConnection.
This connection object contains nodes, edges and pageInfo.
The nodes field is an array optionally containing all the underlying Product objects that matched the pagination and (if any) filter criteria.
The edges field is an array optionally containing a ProductEdge which has both the node outlined above and the cursor. For instance, our example above should be rewritten like this to follow the ProductConnection schema:
query {
products {
edges {
node {
skuCode
}
cursor
}
}
}
This would return something that looked similar to this:
{
"data": {
"products": {
"edges": [
... # a long list, ending in...
{
"cursor": "MTc",
"node": {
"skuCode": "S058700146"
}
},
{
"cursor": "MTg",
"node": {
"skuCode": "S058700145"
}
},
{
"cursor": "MTY",
"node": {
"skuCode": "S058700144"
}
}
]
}
}
If we want to paginate on it, we need to include this cursor field and then retry the query passing the cursor as an argument. In production you'd use Variables for this purpose, but here it's hardcoded. The cursor of the last item we got in a previous call was "MTY", so our next call will ask for items after this cursor, like this:
query {
products(after: "MTY") {
edges {
node {
skuCode
}
cursor
}
}
}
If we want to know whether there are any more results, we can also query for the PageInfo field defined in connection objects. This page info allows us to evaluate whether we have reached the end of our paginated list and automatically supplies the "last" cursor in a list of objects returned by the API. Check the schema docs for PageInfo for more information on what is available to you on the Connection objects.
If you want to know more about GraphQL pagination & connections check out the official docs here.
This ends the series of guides designed to help you make your first call to the Zencargo API. If you've followed along, you should be able and ready to start making basic calls to the API to query and mutate data.
You probably now need to know about how we model the supply chain, and how you can map your system to ours. Continue to the Concepts guide to learn in more depth about this.