Limit, Paging Default Support for Resolvers returning lists
Limit or the possibility to page a GraphQL Resolver is a common usecase.
It would be nice if this is a standard feature in the underlying graphql invoker of resolvers implemetation
following query:
query{
p1: person(id: 1) {
adresses(limit: 15, start: 0)
{
street
}
}
}
should work with following resolver:
@GraphQLApi
public class PersonResource {
@Inject
AdressService adressService ;
@Inject
PersonRestApi personRestApi;
@Query
public Person getPerson(@Name("id") long id) throws ApiException, InterruptedException {
Thread.sleep(2000);
return personRestApi.load(id);
}
public List<Adress> getAdresses(@Source Person p) {
return adressService .getAdresses(p.getId());
}
}
Result:
person 1 with the first 15 assigned adresses
The invoker of PersonResource .getAdresses(..) should limit and page the returning List<Adress> from 0 to 15. (imaging you have an legacy AdressService which can NOT limit, order, page the result on its own)
Linked to https://github.com/eclipse/microprofile-graphql/issues/29. We can support this in SmallRye before we move this to the spec. Again, PR's are welcome :)
Is there something special that is required for pagination?
I'm using this and that seems to work exactly as expected
public Uni<List<Address>> addresses(@Source Person person, @Name("start") @DefaultValue("0") int start, @Name("limit") @DefaultValue("50") int limit) {
return client.preparedQuery("""
SELECT id, name FROM addresses WHERE person_id = $1 LIMIT $2 OFFSET $3""")
.execute(Tuple.of(person.getId(), limit, start))
.map(set -> Streams.stream(set)
.map(row -> new Address
row.getUUID("id"),
row.getString("name")
)).collect(Collectors.toList())
);
}
Then in docs under type Person the field addresses is documented as
addresses(start: Int = 0; limit: Int = 50): [Address]
@diversit what you did is the only current way to do this. We are considering making this easier with a @Pagination annotation. But under the covers it will do what you did.