Build Laravel 5.8 RESTful API CRUD With Authentication Using Passport

In this tutorial, I’m going to show you how to build Laravel RESTful API with authentication using the passport. We are going to use Laravel’s API resources to build RESTful API. We will create Login, Register and Book CRUD API.

Table of Contents

Follow this few steps to create Laravel RESTful API:

  1. Install Laravel and Basic Configurations
  2. Install Passport Package
  3. Migrate and Install Passport
  4. Passport Configuration
  5. Create Book Table
  6. Create Model and Controllers
  7. Create API Routes
  8. Call API using Postman

Step 1 : Install Laravel and Basic Configurations

Any kind of Laravel project needs this thing. For this reason, I’ve created a topic on this. Please see this part from here: Install Laravel and Basic Configurations

Step 2 : Install Passport Package

composer require laravel/passport

We need to add PassportServiceProvider to app.php. Open config/app.php file and add this line:

config/app.php
'providers' =>[
    Laravel\Passport\PassportServiceProvider::class,
],

Step 3 : Migrate and Install Passport

We require to run the migration command. After migration, we will see some tables in the database:

php artisan migrate

Now we need to install passport by running this command:

php artisan passport:install

Step 4 : Passport Configuration

Now we have to configure three files called User.php, AuthServiceProvider.php and auth.php. Open app/User.php and paste this code:

app/User.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

Edit app/Providers/AuthServiceProvider.php and paste this code:

app/Providers/AuthServiceProvider.php
<?php

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];


    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();


        Passport::routes();
    }
}

Open config/auth.php and paste this code:

config/auth.php
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],

Step 5 : Create Book Table

To create a books table run this artisan command:

php artisan make:migration create_books_table

Go to database/migrations folder and you will find the newly created migration file. Open the file and put the bellow code:

date_153350_create_books_table.php
<?php

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

class CreateBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->text('author');
            $table->timestamps();
        });
    }

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

Now run the migrate php artisan command:

php artisan migrate

Step 6 : Create Model and Controllers

We are going to create a model and two controllers for this project. First, run this artisan command to create the Book model:

php artisan make:model Book

Open the book app/Book.php and put this code:

app/Book.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'author'
    ];
}

Now create BookController in API folder by this command:

php artisan make:controller API/BookController

Put the bellow code to the controller:

app/Http/Controllers/API/BookController.php
<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Book;
use Validator;

class BookController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $books = Book::all();
        $data = $books->toArray();

        $response = [
            'success' => true,
            'data' => $data,
            'message' => 'Books retrieved successfully.'
        ];

        return response()->json($response, 200);
    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $input = $request->all();

        $validator = Validator::make($input, [
            'name' => 'required',
            'author' => 'required'
        ]);

        if ($validator->fails()) {
            $response = [
                'success' => false,
                'data' => 'Validation Error.',
                'message' => $validator->errors()
            ];
            return response()->json($response, 404);
        }

        $book = Book::create($input);
        $data = $book->toArray();

        $response = [
            'success' => true,
            'data' => $data,
            'message' => 'Book stored successfully.'
        ];

        return response()->json($response, 200);
    }


    /**
     * Display the specified resource.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $book = Book::find($id);
        $data = $book->toArray();

        if (is_null($book)) {
            $response = [
                'success' => false,
                'data' => 'Empty',
                'message' => 'Book not found.'
            ];
            return response()->json($response, 404);
        }


        $response = [
            'success' => true,
            'data' => $data,
            'message' => 'Book retrieved successfully.'
        ];

        return response()->json($response, 200);
    }


    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Book $book)
    {
        $input = $request->all();

        $validator = Validator::make($input, [
            'name' => 'required',
            'author' => 'required'
        ]);

        if ($validator->fails()) {
            $response = [
                'success' => false,
                'data' => 'Validation Error.',
                'message' => $validator->errors()
            ];
            return response()->json($response, 404);
        }

        $book->name = $input['name'];
        $book->author = $input['author'];
        $book->save();

        $data = $book->toArray();

        $response = [
            'success' => true,
            'data' => $data,
            'message' => 'Book updated successfully.'
        ];

        return response()->json($response, 200);
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Book $book)
    {
        $book->delete();
        $data = $book->toArray();

        $response = [
            'success' => true,
            'data' => $data,
            'message' => 'Book deleted successfully.'
        ];

        return response()->json($response, 200);
    }
}

Now create UserController in API folder:

php artisan make:controller API/UserController

Now paste this code:

app/Http/Controllers/API/UserController.phpp
<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\User;
use Validator;

class UserController extends Controller
{
    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);

        if ($validator->fails()) {
            $response = [
                'success' => false,
                'data' => 'Validation Error.',
                'message' => $validator->errors()
            ];
            return response()->json($response, 404);
        }

        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] = $user->createToken('MyApp')->accessToken;
        $success['name'] = $user->name;

        $response = [
            'success' => true,
            'data' => $success,
            'message' => 'User register successfully.'
        ];

        return response()->json($response, 200);
    }

    /**
     * Login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login()
    {
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
            $user = Auth::user();
            $success['token'] = $user->createToken('MyApp')->accessToken;

            return response()->json(['success' => $success], 200);
        } else {
            return response()->json(['error' => 'Unauthorised'], 401);
        }
    }
}

Step 7 : Create API Routes

In this step, we are going to create API routes. Open routes/api.php and paste this code:

routes/api.php
<?php

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::post('register', 'API\UserController@register');
Route::post('login', 'API\UserController@login');

Route::middleware('auth:api')->group( function () {
    Route::resource('books', 'API\BookController');
});

Coding part is done. Run your application by this command:

php artisan serve

Now the application is running. Let’s call our API using Postman. We need to pass this header details:

'headers' => [

    'Accept' => 'application/json',

    'Authorization' => 'Bearer '.$accessToken,

]

Step 8 : Call API Using Postman

Open the postman app and call the APIs like bellow. Note: I’ve created a custom domain for this project. Your API link should look like http://localhost:8000/api/. If you want to use a custom domain like me, read this article: How to add Custom Domain and install SSL (HTTPS) on Localhost

Register API: Verb: POST, URL: http://laravel_api.test/api/register

Login API: Verb: POST, URL: http://laravel_api.test/api/login

Create Book API: Verb: POST, URL: http://laravel_api.test/api/books

All Books API: Verb: GET, URL: http://laravel_api.test/api/books

Show Single Book API: Verb: GET, URL: http://laravel_api.test/api/books/1

Update Book API: Verb: PUT, URL: http://laravel_api.test/api/books/1

Delete Book API: Verb: DELETE, URL: http://laravel_api.test/api/books/1

Completed. You can download this project from GitHub. I hope this article will help you.