tiagopog / jsonapi-utils

Build JSON API-compliant APIs on Rails with no (or less) learning curve.
MIT License
216 stars 80 forks source link

Add support for custom paginators #30

Closed austenito closed 8 years ago

austenito commented 8 years ago

Hello, it looks like custom paginators aren't supported as JSONAPI::Utils::Support::Pagination looks explicitly for Page and Offset paginators. I'm using version 0.4.6.

Here are the links to the code:

https://github.com/b2beauty/jsonapi-utils/blob/master/lib/jsonapi/utils/support/pagination.rb#L47

and

https://github.com/b2beauty/jsonapi-utils/blob/master/lib/jsonapi/utils/support/pagination.rb#L38

What would be great would to have support for:

If this hasn't been fixed (perhaps I missed a configuration option), I can give this a shot.

tiagopog commented 8 years ago

Hey there, @austenito! As you pointed, JSONAPI::Utils still doesn't support neither custom paginators nor pagination strategy per resource; as well as there's a lack of support for cursor-based pagination strategy.

Now I'm implementing a better support for custom filters and I will probably do some refactoring on JSONAPI::Utils::Support::Pagination, since the code there is same from the first POCs that I made for the gem.

It would be really great to see a PR implementing those features for pagination 👍

austenito commented 8 years ago

@tiagopog I'll give it a shot!

Also, I believe cursor pagination was removed https://github.com/cerebris/jsonapi-resources/issues/301

tiagopog commented 8 years ago

Indeed it was removed in JR, but since there's a growing adoption of some databases with cursor-based pagination (e.g. Google Cloud Datastore) it would be nice to bring a paginator that supports it.

You could start by implementing the support for custom paginator and later we could think on a proper way to deal with cursos.

tiagopog commented 8 years ago

👀 #27

tiagopog commented 8 years ago

Just took a free time tonight to refactor the module JSONAPI::Utils::Support::Pagination. Hope it helps you.

austenito commented 8 years ago

@tiagopog nice refactor :)

One of the things I've been thinking about is how to handle the pagination via ranges since custom paginators handle ranges differently. For example:

def pagination_range
  case JSONAPI.configuration.default_paginator
  when :paged
    number = page_params['number'].to_i.nonzero? || 1
    size   = page_params['size'].to_i.nonzero?   || JSONAPI.configuration.default_page_size
    (number - 1) * size..number * size - 1
  when :offset
    offset = page_params['offset'].to_i.nonzero? || 0
    limit  = page_params['limit'].to_i.nonzero?  || JSONAPI.configuration.default_page_size
    offset..offset + limit - 1
  end
end

I was thinking about delegating to each paginator to return the appropriate range. Anyways, I hope to get a branch up soon for you 👀 at :)

tiagopog commented 8 years ago

Delegate this kinda job to paginators would be the ideal scenario, the thing is: JSONAPI::Resources doesn't support rendering Array of Hashes – the use case where range is used for pagination – then we should open the default paginator classes or stuff to add this behavior. I'm avoiding to monkey patch things as much as I can, so that I prefered to write this method rather than changing a few objects at runtime.

Thanks for the coming PR, I'm sure it will be awesome! Cheers!