Logo

Laravel API Resource + Vue.js Pagination (Part One)

In this short tutorial i will show you how you can easily paginate your api-resources using Vue.js

Laravel provides since version 5.5 own api-transformers to transform your eloquent models into JSON. This could be very handy in a lot of situations when you build API´s using Laravel.

But how can you consume and paginate the results of your api within your application using Vue.js? In this tutorial, i will show you how to manage the pagination of your results.

What you will need

I assume that you have Laravel Valet and the Laravel Installer installed on your machine. I also assume that you know the basics of working with Eloquent-Resources in Laravel. And i assume that you have a basic knowledge of Bootstrap 4, since we´re using BS4 for this example.

Creating a new Laravel Project

Open up your terminal and type

laravel new pagination-example

This will setup a new laravel 5.6 application on your machine.

Now "cd" into your application by typing

cd pagination-example

Prepare a demo-model

We need demo-data. We need a lot of demo-data. Laravel will help us, creating this data using the model-factories.

But first we need a model, a migration and an idea of what we want to paginate (Oranges, Apples, Cars, WHATEVER!).. I´ll choose simple persons for this example, since i created some projects with data like most people have 😆.

Type

php artisan make:model Person -m

This will create a new model within your app/ directory called Person and a new migration file within your database/ directory called something like 2018_05_03_create_persons_table.php.


This is how my Person model looks like:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePeopleTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('people', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email');
            $table->string('city');
            $table->string('country');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('people');
    }
}

Type

php artisan migrate

to migrate your database.

The Eloquent Resource

Now that we have our model and migration in place, we also need a eloquent-resource. You can easily create one by typing

php artisan make:resource PersonResource

This will create a new file called PersonResource within your app/Http/Resources/ directory.

Now prepare your model to allow mass-assignment with our data:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Person extends Model
{
    protected $guarded = [];
}

Creating the model-factory

Creating a model-factory is pretty simple. You basically just need to type

php artisan make:factory PersonFactory --model=Person

into your terminal and thats all. (No.. I´m just kidding 😆)

Edit your Person factory like this:

<?php

use Faker\Generator as Faker;

$factory->define(App\Person::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'city' => $faker->city,
        'country' => $faker->country
    ];
});

Faking the data

We still need data. To create the data, just type

php artisan tinker

into your terminal followed by

$persons = factory('App\Person', 30)->create();

once tinker is loaded. After you pressed enter you will now see an array of mock-data for our resource.

Giving back JSON (Collection)

Now that we have almost everything in place for our test-application, we still need to provide the data.. Eloquent-Resources are very smart. You can pass an array or an object to the resource and it will automatically map the data into a json-collection / json-object.

We now need to display the data by modifying our routes/web.php file like this:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $persons = \App\Person::paginate(5);

    return \App\Http\Resources\PersonResource::collection($persons);
});

This will give us a collection of all persons in our database when you open up http://pagination-example.test in your browser.

Giving back JSON (Object)

As i told you before, the resource can also handle simple objects.. To only show one from our collection, modify the routes/web.php file like this:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// Collection
Route::get('/', function () {
    $persons = \App\Person::paginate(5);

    return \App\Http\Resources\PersonResource::collection($persons);
});

// Object
Route::get('{id}', function ($id) {
    $person = \App\Person::find($id);

    return \App\Http\Resources\PersonResource::make($person);
});

This will give us a simple object of the person with the ID of 1 in our database when you open up http://pagination-example.test/1 in your browser.

Conclusion

This was part one of the two-parted series "Laravel API Resource + Vue.js Pagination". In the next part, i will show you how to manage the vue-part of our example.

You can find the source for this part on GitHub.

Let's stay in touch

Sign up for my newsletter and I will let you know about more content and new projects of mine once a month.