Posted by Arjun on Sunday 16th October 2016

Create REST API with the Laravel 5.5

Laravel 5.x create laravel 5.3 REST API Laravel 5.5

This tutorial provides an example of building a complete RESTful API using Laravel 5.5.* Framework. You gonna use the different HTTP methods during the REST API development, quick introduction about each method.

GET to retrieve data
POST to add data
PUT to update data
DELETE to delete data

Each method as a purpose isn't it?. Let's download and install Laravel 5.5.* Framework as the first step. Before installing, Just want to give a quick introduction to the app which you are going to build is TODO application. You can search for todos, add a todo to list, update and delete todos. Exciting right, let's start your journey-

[caption id="attachment_4524" align="aligncenter" width="640"]Create REST applications with the Laravel framework [/caption]

STEP - 1 (Download and install Laravel 5.5.* Framework)

You can setup project with latest version by issue following command from your terminal.

$ composer create-project laravel/laravel todo --prefer-dist

If you want to setup project with a specific version, issue following command from your terminal.

$ composer create-project laravel/laravel todo 5.5 --prefer-dist

Here, "todo" is project name, above command create a directory with project name and downloads all files inside it. Now move control to your project directory(todo) by issuing below command and serve application by using artisan command.

 $ cd todo
 $ php artisan serve

It will show http://localhost:8000/ URL if it is up successfully.

That's about installation and congratulation, you have finished step one successfully. Let's create make database configurations.

Configure Your Database

Create a database and edit .env and fill it with your database settings. This article assumes a MySQL database.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password

Create Migration File

Below command set up the basic migration scripts that we'll be using to create the database table.

 php artisan make:migration create_tasks_table --create=tasks

Now required migration file is in place, so let's add a table column as shown below.

Edit app/database/migrations/SOME_DATE_create_tasks_table.php and edit and update the up() and down() methods:

public function up() {
   Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->text('description');
            $table->integer('user_id');
            $table->timestamps();
   });
}
public function down() {
    Schema::dropIfExists('tasks');
}

Add Sample Users and todos

We gonna use Laravel's seeds to create a few sample users and todos.

Let issue following commands to create seeder class from your root of the project.

php artisan make:seeder UsersTableSeeder 
php artisan make:seeder TasksTableSeeder

Generated seeders by the above commands will be placed in the database/seeders directory. In our case, we have two seed files called UsersTableSeeder.php and TasksTableSeeder.php.

Update seeder run methods as shown below
UsersTableSeeder.php

    public function run()
    {
        factory(App\User::class, 50)->create();
    }

TasksTableSeeder.php

    public function run()
    {
        factory(App\Task::class, 50)->create();
    }

Next, make sure that seeder class gets run when the database is seeded. Edit app/database/seeds/DatabaseSeeder.php

    public function run()
    {
         $this->call(UsersTableSeeder::class);
         $this->call(TasksTableSeeder::class);
    }

Add Model Factories

Next, create app/database/factories/UserFactory.php and app/database/factories/TaskFactory.php and place below code blocks

<?php
// app/database/factories/UserFactory.php
use Faker\Generator as Faker;

$factory->define(App\User::class, function (Faker $faker) {
    static $password;
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});
<?php
// app/database/factories/TaskFactory.php
use Faker\Generator as Faker;
$factory->define(App\Task::class, function (Faker $faker) {
    $users = App\User::pluck('id')->toArray();
    return [
        'name' => $faker->unique()->name,
        'description' => $faker->text,
        'user_id' => $faker->randomElement($users)
    ];
});

Create Task Model

Laravel comes with a User model setup, so let's create a model for our tasks table.

Create a modal with

$ php artisan make:model Task

since you are following Laravel naming conventions you don't have to change anything in the task model.

Run the Migrations

Below are the Laravel's artisan commands and issue below commands from your project root. These commands will create those tables and inset sample users and tasks to the database.

// Create the tables for migrations
$ php artisan migrate
 
// Create the sample users and tasks
$ php artisan db:seed

api-response

When building an API it is common for people to just grab stuff from the database and pass it to json_encode(). This might be passable for “trivial” APIs but if they are in use by the public, or used by mobile applications then this will quickly lead to inconsistent output. So to avoid this problems we gonna use ellipsesynergie/api-response package. This package handles the response properly in your API and this package uses Fractal.

Fractal - Fractal provides a presentation and transformation layer for complex data output, the like found in RESTful APIs, and works really well with JSON. Think of this as a view layer for your JSON/YAML/etc.

Install package with the composer, issue the command from your root of the project:

composer require ellipsesynergie/api-response

Add this following service provider to your config/app.php file.

EllipseSynergie\ApiResponse\Laravel\ResponseServiceProvider::class

Create Task Controller

$ php artisan make:controller TaskController

Now define your api routes in routes/api.php

// get list of tasks
Route::get('tasks','[email protected]');
// get specific task
Route::get('task/{id}','[email protected]');
// delete a task
Route::delete('task/{id}','[email protected]');
// update existing task
Route::put('task','[email protected]');
// create new task
Route::post('task','[email protected]');

Lets update task controller with below code, please read comments for better understanding.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use EllipseSynergie\ApiResponse\Contracts\Response;
use App\Task;
use App\Transformer\TaskTransformer;

class TaskController extends Controller
{
    protected $respose;

    public function __construct(Response $response)
    {
        $this->response = $response;
    }

    public function index()
    {
        //Get all task
        $tasks = Task::paginate(15);
        // Return a collection of $task with pagination
        return $this->response->withPaginator($tasks, new  TaskTransformer());
    }

    public function show($id)
    {
        //Get the task
        $task = Task::find($id);
        if (!$task) {
            return $this->response->errorNotFound('Task Not Found');
        }
        // Return a single task
        return $this->response->withItem($task, new  TaskTransformer());
    }

    public function destroy($id)
    {
        //Get the task
        $task = Task::find($id);
        if (!$task) {
            return $this->response->errorNotFound('Task Not Found');
        }

        if($task->delete()) {
             return $this->response->withItem($task, new  TaskTransformer());
        } else {
            return $this->response->errorInternalError('Could not delete a task');
        }

    }

    public function store(Request $request)  {
        if ($request->isMethod('put')) {
            //Get the task
            $task = Task::find($request->task_id);
            if (!$task) {
                return $this->response->errorNotFound('Task Not Found');
            }
        } else {
            $task = new Task;
        }

        $task->id = $request->input('task_id');
        $task->name = $request->input('name');
        $task->description = $request->input('description');
        $task->user_id =  1; //$request->user()->id;

        if($task->save()) {
            return $this->response->withItem($task, new  TaskTransformer());
        } else {
             return $this->response->errorInternalError('Could not updated/created a task');
        }

    }

}

Create a Transformer folder in your app directory and create a file called app\Transformer\TaskTransformer.php with below code

<?php namespace App\Transformer;

use League\Fractal\TransformerAbstract;
 
class TaskTransformer extends TransformerAbstract {
 
    public function transform($task) {
        return [
            'id' => $task->id,
            'task' => $task->name,
            'task_description' => $task->description
        ];
    }
 }

That's it.Rest APIs are ready now you can access the APIs with below-shown endpoints using advance reset client or Curl.

Start the server with php artisan serve or use other other methods.

 URL                          HTTP Method  Operation
/api/task                     GET          Returns an array of tasks
/api/task/:id                 GET          Returns the task with id of :id
/api/task                     POST         Adds a new task and return it.
/api/task/:id                 PUT          Updates the task with id of :id
/api/task/:id                 DELETE       Deletes the task with id of :id