Coming up with a paging infrastructure for the API while looking at all of the ways it could be used and abused hasn’t been fun. Not that it hasn’t been totally worthwhile. I’ve actually learned a lot more about some of the nuances of how ActiveRecord and related libraries are building up their queries. I’ve thought a lot more about the nature of the queries within Diaspora too. At the same time my head is numb and for all of the effort I only got a half completed design and less than 100 lines of code across two classes, not that more lines is necessarily better.
So what we will have are two paginator types: index based and time based. The standard methods across the two are:
- page_data: returns the current page of data for passed in query
- next_page: returns information to go to the next page of data
- previous_page: returns information to go to the previous page of data
The previous/next page functions will either return a new paginator object that corresponds to the next page or it will return a string that represents query parameters that can be passed back out from a REST endpoint.
Both paginator types take a query object that will then have additional paging stuff wrapped around it. If one is doing an index-based query this is just wrapping the WillPaginate library. However if one is doing a time based query then it’s a little more complicated than that. We aren’t simply moving around indexes we actually are doing some time math. That is all coded directly in the class. The big difference between the two comes in how the ordering happens on the SQL query. In the case of both you can pass in an ordered query without throwing an error. However in the case of the IndexPaginator one probably wants to pass in their preferred order otherwise they’ll get whatever the natural order from the database is. In the case of the TimePaginator it wants to keep control over sorting by whichever time field the calling code is using. Therefore adding an additional sort could create confusing results.
Now that the paginators are done I need to add a present class that knows how to turn the query parameters into a “link” field with full URLs, per the API specification, and to update the services to call into and return the paginated data instead of their current form. I think I’ll do one that uses indexes, like contacts, followed by one that uses time, like user posts, and then start filling it out the rest of the way from there.
In summary:
- Completed playing around with the base pagination classes and completed them.
- Starting to wire in first pagination into some first endpoint