Pagination
Pagination is required in most queries that return lists of items in the Saleor GraphQL API. It limits the number of results returned by the server to a more manageable size and avoids data flow disruptions.
Relay specification
Saleor's pagination model is based on the GraphQL Connection Specification but contains some extra fields added for your convenience.
If your GraphQL client supports Relay-style pagination, you can use it with Saleor and skip reading the rest of this page.
- Apollo documentation on Relay-style pagination
- Relay documentation on pagination
API reference
Saleor uses cursor-based pagination, meaning that each item is assigned a unique cursor instead of page numbers. The API clients can ask for a certain number of items following or preceding a given item.
Lists vs. connections
There are two types of lists in GraphQL:
-
[Foo]
is a simple list. It is used to query a list containing several items.An excellent example of a simple list could be a query for product variants which returns a list with a manageable number of results.
-
FooConnection
represents a more complex list. When queried, it will return an unknown or large number of results.
Pagination is used to help you handle large amounts of items returned by the connection list type.
<Entity>Connection
type ProductCountableConnection {
edges: [ProductCountableEdge!]!
pageInfo: PageInfo!
totalCount: Int
}
Each connection contains the following fields:
-
edges
: the list of edges (see below). -
pageInfo
: information on the pagination result (see below).
In addition to the above, countable connections contain:
-
totalCount
: the total number of items of that type.cautionRequest
totalCount
sparingly as it is very expensive to calculate.
<Entity>Edge
type ProductCountableEdge {
node: Product!
cursor: String!
}
Each node contains the following fields:
-
node
: an individual result (for example, a product). -
cursor
: the cursor representing the place where the node is located.
PageInfo
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
-
hasNextPage
: indicates if there are more items to be fetched. Only calculated for queries usingfirst
. -
hasPreviousPage
: indicates if there are items prior to the current page. Only calculated for queries usinglast
. -
startCursor
: the cursor of the first item inedges
. Use it asbefore
to paginate backwards. -
endCursor
: the cursor of the last item inedges
. Use it asafter
to paginate forwards.
You can use the PageInfo
object to know whether the previous or next page exists (hasPreviousPage
, hasNextPage
) and how to reach them (startCursor
, endCursor
). You can also use individual cursor
values returned with each node, but it's usually less convenient.
For more information about pagination, see the official GraphQL website.
Pagination is subject to usage limits.
Fetching paginated data
To indicate how you want the queried items to be selected, use a combination of the following connection arguments:
-
first
: the number of items (nodes) you want the query to return. This argument will return items from the beginning of the list. The system only allows fetching up to 100 objects in a single query. Cannot be combined withlast
.See code example
query {
products(first: 10) {
edges {
node {
id
name
}
}
}
} -
last
: the number of items (nodes) you want the query to return. This argument will return items from the end of the list. The system only allows fetching up to 100 objects in a single query. Cannot be combined withfirst
.See code example
query {
products(last: 10) {
edges {
node {
id
name
}
}
}
} -
after
: the cursor you want to start from. Pass thecursor
of the last item from the previously fetched chunk and combine it withfirst
to paginate through data in equally sized chunks.See code example
query {
products(first: 10, after: "YXJyYXljb25uZWN0aW9uOjA=") {
edges {
node {
id
name
}
}
}
} -
before
: the cursor you want to end with from. Pass thecursor
of the first item from the previously fetched chunk and combine it withlast
to paginate through data in equally sized chunks.See code example
query {
products(last: 10, before: "YXJyYXljb25uZWN0aW9uOjQ==") {
edges {
node {
id
name
}
}
}
}
Example
You want to display 5 results per page and start with items from the beginning of the list.
- Query the
first: 5
nodes. This becomes your first page.- If you have more results to show, query the following
first: 5
nodesafter
the node indicated by the value of the cursor of the fifth node. This becomes your second page.- For the third page, query the following
first: 5
nodesafter
the node indicated by the cursor of the tenth node.When you want to start displaying the results from the end of the list, you use
last
andbefore
respectively.