-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Hi,
I'm using hapipal with lots of their packages. My ORM is schwifty/objection.js. I'm new to the hapi/hapipal stack.
First try
The first thing I noticed is that hapi-pagination doesn't format the results itself because it doesn't know what ORM you're using (#11 #12).
Objection makes this pretty easy with its page(page, pageSize) method.
So my first draw was this:
'use strict';
module.exports = {
method: 'GET',
path: '/clients',
options: {
tags: ['api'],
handler: async (request) => {
const result = await request
.models()
.Clients
.query()
.page(request.query.page, request.query.limit);
request.totalCount = result.total;
return result;
}
}
};The problem with this is that I'd have to .page(request.query.page, request.query.limit) and request.totalCount = result.total every GET requests where I'd want pagination. I don't like going this way because there are lot of code replication.
Second try
That's where I'd like your advices.
What I did to overcome this is creating a hapijs plugin:
'use strict';
const paginate = async function (query) {
const result = await query.page(this.request.query.page, this.request.query.limit);
this.request.totalCount = result.total;
return this.response(result);
};
exports.plugin = {
name: 'app-paginate',
version: '0.1.0',
register(server, options) {
server.decorate('toolkit', options.paginateMethod || 'paginate', paginate);
server.app.paginateMethod = options.paginateMethod;
}
};It's a decorator. It automatically finishes the DB request with .page and append the totalCount required for hapi-pagination to the request.
The decorator is called from the route like this:
'use strict';
module.exports = {
method: 'GET',
path: '/clients',
options: {
tags: ['api'],
handler: async (request, reply) => {
return await reply[request.server.app.paginateMethod](
request.models().Clients.query()
);
}
}
};reply[request.server.app.paginateMethod](query) translates to reply.appPaginate(query) because server.app.paginateMethod was set previously to options.paginateMethod, and options.paginateMethod is set into the Glue Manifest:
{
plugin: './plugins/paginate',
options: {
paginateMethod: 'appPaginate'
}
}Is this second try a good way to achieve my pagination? Maybe there are better ways to do this, I'd like some advices.