Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is this a good way to wrap the pagination logic? #71

Open
orditeck opened this issue Oct 25, 2018 · 0 comments
Open

Is this a good way to wrap the pagination logic? #71

orditeck opened this issue Oct 25, 2018 · 0 comments

Comments

@orditeck
Copy link

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.

@orditeck orditeck changed the title Is this a good way to wrap the pagination? Is this a good way to wrap the pagination logic? Oct 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant