Reputation: 39
How can we create a paginated query using graphql spqr, java, mongo?
Below is how query would look like:
allUsers(first : int, last :int, after : String, before: String)
Upvotes: 0
Views: 1302
Reputation: 15499
No Spring
If you want SPQR to automatically map the result as a Relay page, make sure you return a Page<>
from your method. So something like:
public Page<User> allUsers(int first, int last, String after, String before) {
List<User> users = queryMongo(...); //however you query Mongo
return translateListToPage(users); //get a Page instance somehow, see below
}
I don't know if you can do real cursor-based pagination in Mongo (where you give it the last seen cursor and ask for the next batch of items), but if not you can always translate it to simple offset-based pagination or use a value of any field you can sort on as the cursor.
See my answer here for an idea how to implement these approaches. It describes a solution meant for a relational DB but the logic is the same. E.g. you use cursor.skip
and cursor.limit
instead of SQL's LIMIT
and OFFSET
.
In short, you can do something like:
public Page<User> allUsers(int first, String after) {
//Treat 'after' as the offset to skip to
int skip = Integer.valueOf(after);
//Query Mongo (this is Mongo shell, do whatever you normally do in Java instead)
List<User> users = db.users.find().skip(skip).limit(first);
//Translate to Page
Page<User> userPage = PageFactory.createOffsetBasedPage(users, totalUserCount, skip);
return userPage;
}
There's many more ways to create a Page
instance, including creating your own implementation of that interface.
Another way is something like:
public Page<User> allUsers(int first, String after) {
//This time 'after' is the last seen ID
List<User> users = db.students.find({'_id': {'$gt': after}}).limit(first);
//Translate to Page somehow again (you have to somehow know if there's the next/previous page)
Page<User> userPage = PageFactory.createPage(users, (user, ix) -> () -> user.getId(), hasNextPage, hasPreviousPage);
return userPage;
}
Spring Data
If you're using Spring Data, you can return org.springframework.data.domain.Page
(or Slice
) and configure SPQR to map that as a Relay page. This feature will be supported out-of-the-box in the next release of SPQR Spring Boot Starter.
Upvotes: 1