REST way of doing pagination


#1

I was having a discussion with a great friend on what “REST way of
paginating” means.

Without polluting your minds initially with the ideas we discussed,
I’d like to get everyones thoughts as to what this might mean and how
you envision it being implemented.

~Wayne


#2

Hey,

I see nothing inherently “unRESTful” about pagination in the style
people generally do it in rails.

As in: GET /some/resource?page=35 is a perfectly valid action and URL
(from a REST perspective) which uniquely describes the resource you
are looking for (“page 35 of whatever /some/resource is”).

So my answer to your questions would be: “the way it works now”.

Perhaps you might give just a little background on why you think
the current style is not RESTful.

HTH
Trevor

On 6/15/07, Cogaidhean removed_email_address@domain.invalid wrote:

Trevor S.
http://somethinglearned.com


#3

Thanks for the response Trevor.

We do not see anything “unRESTful” about it either nor do I view the
current system as not RESTful. We were simply wondering if there was
something subtle and/or obvious that we were missing pertaining to
REST. Our basic view is that the will_paginate method is the best way
thus far (that we’ve seen).


#4

Trevor,

Our discussions finally ended up along the lines of:
a RESTful way would, perhaps, be to abstract the pages themselves as a
nested resource object. An example:

/posts/4/pages/2

where the pages/2 gets translated into parameters but from the
abstract we’re saying that it would return an object which is a “set”
of posts.

But this was just a half baked concept as we fiddled with the meaning
of “REST” in addition to the concept of “pretty url’s”.


#5

Ah okay,

I assumed that you were implying that pagination as it’s done now is
not “the REST way of paginating”.

Often people talk about whether something is RESTful when in fact they
mean something more like RAILSy (pretty urls, the mapping of certain
urls to certain actions).

I’ve had more than a few conversations with people who were trying to
eliminate ?param=value from their URLs because they (erroneously,
imho) believed the params somehow violated REST.

But I am curious to know what ideas came out of the discussion you
mentioned.

Trevor

On 6/15/07, Cogaidhean removed_email_address@domain.invalid wrote:

Trevor S.
http://somethinglearned.com


#6

On 6/15/07, Cogaidhean removed_email_address@domain.invalid wrote:

abstract we’re saying that it would return an object which is a “set”
of posts.

But this was just a half baked concept as we fiddled with the meaning
of “REST” in addition to the concept of “pretty url’s”.

That’s not a bad idea. One problem is you don’t want them going to a
PagesController or anything like that. What about this?

map.resources :posts do |post|
post.pages # sets up /articles/:article_id/pages/:page routes for
the articles controller
post.resources :comments
end

Weekend plugin challenge!


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com


#7

On 6/15/07, Trevor S. removed_email_address@domain.invalid wrote:

I’ve experimented with a hack or two that tried to address #2 by
changing with_options to pass more than one OptionMerger but
ultimately it’s pointless because of #3.

Sorry, that probably came across as “you can’t get there from here” -
which is clearly not the case. Nothing is impossible, I’m just saying
that overcoming the limitations I mention would probably mean
non-trivial tinkering with how the mapper and/or resource() and
resources() behave.

Trev

Trevor S.
http://somethinglearned.com


#8

Hey Rick,

I’ve already gone through a similar loop (and as it happens, have a
plugin that I’m currently running through its paces) for ‘canned
reports’:

map.report_on :sales do |sales|
sales.today #=> /sales/today calls today()
sales.for_year ‘during/:year’ #=> /sales/during/:year calls for_year()
end

It’s pretty trivial to do this sort of thing as long as you work
within the limitations of the route mapper.

1 the only bit of context passed into your blocks is path_prefix and
name_prefix

this means that you don’t have access to a :controller option when
your pages() method (or my report_on() method) is called. And
implicitly passing the :controller in the scope would be interpreted
as manually overriding the controller for other methods like
resources().

2 for map.resources, the path_prefix given to your block is for the
member and not the collection.

3 there’s little point trying to overcome #2 because by the time your
block executes it’s too late to define any /pages urls for the
collection. As in /posts/pages will be picked up by the route for
/posts/:id

I’ve experimented with a hack or two that tried to address #2 by
changing with_options to pass more than one OptionMerger but
ultimately it’s pointless because of #3.

Wayne, I’d be happy to let you see my code before it’s released (if
indeed it ever does get released), just send me a note off-list.

Regards,
Trevor

On 6/15/07, Rick O. removed_email_address@domain.invalid wrote:

map.resources :posts do |post|
http://weblog.techno-weenie.net
http://mephistoblog.com

Trevor S.
http://somethinglearned.com


#9

On Jun 15, 5:43 pm, “Rick O.” removed_email_address@domain.invalid wrote:

map.resources :posts do |post|
post.pages # sets up /articles/:article_id/pages/:page routes for the articles controller

Excellent, I wasn’t aware of that!

Is this new in edge or something? It looks like you’re about to
define a named route called ‘pages’ but then you never specify the
route.

Jeff


#10

On 6/15/07, Jeff removed_email_address@domain.invalid wrote:

It’s something I made up. I don’t intend to write it anything.


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com


#11

/posts/4/pages/2

I’m not partial to this way of referencing pages, if it refers to a
changing collection. Slashes indicate a fairly “hard” definition of a
path to some resource. If you add items to the collection and the
result set of each page changes, this URL doesn’t refer to the same
thing. I think of the page parameter more like a search (i.e.
filtering) query in this case.

Just another opinion…

–Andrew V.


#12

Has anyone made a plugin out of this?


#13

GoogleGroups said my post was successful, but it’s been several hours,
and it isn’t showing up. I’m going to chance a double post here.

What about a URL with a little more semantic meaning? Like
/posts/Cogaidhean/?start_with=2006_9_17&return_count=10 or something?
It just seems so much more ‘discoverable’ that way.

Ron


#14

I wouldn’t mind if the plugin just did:

/posts/2?p=2

maybe i’ll make it when i have time


#15

Not sure if I’m just being lazy or if it would be practical to have a
plugin that automatically used the query provided in your index action
and auto paginated that… am I just being lazy? :slight_smile:


#16

On 19-Jun-07, at 9:35 AM, removed_email_address@domain.invalid wrote:

I wouldn’t mind if the plugin just did:

/posts/2?p=2

maybe i’ll make it when i have time

Lance,

why do you need a plugin for that?

post_path(:id => 2, :stuck_out_tongue: => 2) #=> /posts/2?p=2

Am I missing something?

Trev


#17

Well,

lazy can be a positive thing :slight_smile:

Give it a shot, there might be something interesting there.

Trev


#18

Did you check out the will_paginate plugin? That’s almost exactly
what you’re describing. There’s not really a way to 100% automate the
pagination, but will_paginate comes close.

Jeff

On Jun 20, 9:43 am, “removed_email_address@domain.invalid” removed_email_address@domain.invalid