We have a graphql server (not written in javascript) serving a paginated list of objects. We\'re trying to conform to the relay specification, but we\'ve hit an interesting case
Yes, the cursor should contain enough information in it to enable fetching the next page from that point onwards (including constraints such as sorting and filtering), but whether/how you do this is up to you as it is implementation-specific.
As for mutations, in your getConfigs()
implementation you can specify rangeBehaviors
on a per-call basis. So, if you have a sorted view, you might choose to append or prepend depending on the sort order. This behavior specifies what Relay will do on the client-side to update its store. It's still your responsibility to ensure that the code your GraphQL server receives all the information it needs (via input variables) to correctly perform the actual mutation.
I had the same problem. So, I decided to write a npm
package to handle this issue.
You can use fast-relay-pagination npm package for sorting, backward and forward pagination
and filter Mongoose
model or MongoDB
object.
This package improves graphql-relay
lazy loading by using Mongoose
or MongoDB
find and limit. As you definitely know, graphql-relay's
connectionFromArray
fetchs all data and performs slicing on data, which is not efficient for large amount.
You can see an example in below:
...
import {
fetchConnectionFromArray
} from 'fast-relay-pagination'
...
export default{
type: orderConnection.connectionType,
args: {
...connectionArgs,
orderFieldName: {
type: GraphQLString,
},
sortType: {
type: GraphQLInt,
},
},
resolve: needAdmin(async (_, args) => {
let orderFieldName = args.orderFieldName || '_id'
let sortType = args.sortType || -1
let after = args.after
let before = args.before
let filter = args.filter
let first = args.first
let last = args.last
return fetchConnectionFromArray({
dataPromiseFunc: SampleModel.find.bind(SampleModel), // required
filter, // optional (for using filter on model collection) - for example => {username: 'test'}
after, //optiona
before, // optional
first, //optional
last, // optional
orderFieldName, // optional
sortType, // optional
})
}),
}