Making the Paginator API-friendly in Laravel 4

10 Sep 2013

The Paginator is a great pagination tool in Laravel 4. It easily allows us to create pagination tags and urls that link to the relevant pages a user may wish to browse through when iterating through a result set. However, the Paginator appears to not be designed so well for API consumption, as are Eloquent models or Eloquent collections. So how do we solve that?

First of all, if you haven’t read my previous article, Pagination with Laravel 4 and Angular JS - do so now. It’ll give you some background information as to the need for this article.

Let’s assume we have the following route (from the previous article):

1 // routes.php
2 Route::get( 'posts', function() {
3   return Post::paginate( $limit = 10 );
4 });

Very simple - we’re retrieving a list of posts and paginating them. However, without any extra work you will see an error - as Laravel’s Response has no idea how to deal with a Paginator object. To fix this, all we’re going to do is extend the Paginator and make it a JsonableInterface!

 1 namespace KirkBushell;
 2 
 3 use Illuminate\Pagination\Paginator as OldPaginator;
 4 use Illuminate\Support\Contracts\JsonableInterface;
 5 
 6 class Paginator extends OldPaginator implements JsonableInterface
 7 {
 8   public function toJson($options = 0)
 9   {
10     $json = [
11       'last' => $this->getLastPage(),
12       'page' => $this->getCurrentPage(),
13       'perPage' => $this->getPerPage(),
14       'results' => $this->items,
15       'total' => $this->getTotal()
16     ];
17       
18     return json_encode($json, $options);
19   }
20 }

This tells our Response object that the class is JSON-friendly, and so it will use the toJson() method we defined above to get the results it needs. In this case, it’s a json-encoded array of all the information we need for client-driven pagination. How easy is that?

There’s one last thing we need to do. We need to tell our application where to find this new paginator. I highly recommend adding it to a namespace somewhere in your codebase, and then you can simply do the following in app/config/app.php:

1 'Paginator' => 'KirkBushell\Paginator',

Where you see the Paginator line. Then you’re all done. Remember also that you may need to add your new namespace to the composer.json file and do: composer dumpautoload

This basically tells composer where our new namespace can be found and adds it to the autoload files. I put my paginator at app/KirkBushell/Paginator.

You can now return a paginator object as a response, and Laravel will handle the rest. There’s nothing sweeter than beautiful, DRY code!

Tagged: laravel, pagination
comments powered by Disqus