@lightspeed/graphql-page-connection
v0.1.11
Published
Create relay connections from numbered pages pagination
Downloads
32
Keywords
Readme
@lightspeed/graphql-page-connection
Introduction
Cursor pagination works by returning results after or before a pointer to an item in the dataset. We follow the Relay Cursor Connections Paginatinon Specification for pagination in GraphQL
Using an opaque string value as a cursor, we can abstract away the differences of underyling pagination schemes per endpoint, while giving us a consistent interface to consumers of the API.
This library provides an abstraction over the numbered pages pagination model, in which the data source is expecting a page number and a page size. The cursor is defined as base64('page:<page>;offset:<offset>')
.
Let's observe an example in which we request the first
4 items after
cursor cGFnZTowO29mZnNldDoz
, i.e.: base64('page:0;offset:3')
.
{
"edges": [
{
"node": {
"name": "banana"
},
"cursor": "cGFnZToxO29mZnNldDow" // base64('page:1;offset:0')
},
{
"node": {
"name": "apple"
},
"cursor": "cGFnZToxO29mZnNldDox" // base64('page:1;offset:1')
},
{
"node": {
"name": "pear"
},
"cursor": "cGFnZToxO29mZnNldDoy" // base64('page:1;offset:2')
},
{
"node": {
"name": "watermelon"
},
"cursor": "cGFnZToxO29mZnNldDoz" // base64('page:1;offset:3')
}
],
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": true,
"startCursor": "cGFnZToxO29mZnNldDow", // base64('page:1;offset:0')
"endCursor": "cGFnZToxO29mZnNldDoz" // base64('page:1;offset:3')
},
"totalCount": 45
}
From here, we have a few options:
- To paginate forward, we request the
first
4 itemsafter
end cursorcGFnZToxO29mZnNldDoz
, i.e.:base64('page:1;offset:3')
.- If we request the
first
4 itemsafter
any other cursor, we'll receive an error. The numbered pages pagination model data source does not support this request.
- If we request the
- To paginate backwards, we request the
last
4 itemsbefore
start cursorcGFnZToxO29mZnNldDow
, i.e.:base64('page:1;offset:0')
.- If we request the
last
4 itemsbefore
any other cursor, we'll receive an error. The numbered pages pagination model data source does not support this request.
- If we request the
Quick Start
- Install the dependency in your webapp.
yarn add @lightspeed/graphql-page-connection
- Implement your data fetching logic in the resolver.
import { pageFromConnectionArgs, connectionFromArray } from '@lightspeed/graphql-page-connection';
export const resolvers: ResolverMap = {
Query: {
products: async (_parent, { first, after, last, before }, { dataSources }) => {
// Extract the page number and page size from cursor arguments
const connectionArgs = { first, after, last, before };
const { pageNum, pageSize } = pageFromConnectionArgs(connectionArgs);
// Retrieve data and page metadata from data source
const { productDataSource } = dataSources;
const res = await productDataSource.getProducts({ pageNum, pageSize });
const { data, pageCount, totalCount } = res;
// Create a connection as an output
const meta = { totalCount, pageCount };
const connection = connectionFromArray(products, connectionArgs, meta);
return connection;
},
},
};