REST Api Development in Laravel 8 with Passport

Reading Time: 14 minutes
7,205 Views

Inside this article we will learn one more important concept of laravel i.e REST api development in laravel 8 with Passport. This will be step by step guide to create restful services from scratch.

REpresentational State Transfer (REST) is an architectural style that defines a set of constraints to be used for creating web services. REST API is a way of accessing web services in a simple and flexible way without having any processing.

In this article we will create a secure set of rest apis using laravel using Passport. Passport is a laravel composer package.

What we will do in this article –

  • User Register API
  • Login API
  • Profile API
  • Logout API
  • Create Blog
  • List Blog
  • Single Blog details
  • Update Blog
  • Delete Blog

Above are the apis, we will create using passport authentication. This will be very interesting to learn.

  • To Learn API development in Laravel 8 Using JWT Authentication, Click here.
  • REST APIs in Laravel 8 Using Sanctum Authentication, Click here.

Let’s get started.


Laravel Installation

We will create laravel project using composer. So, please make sure your system should have composer installed. If not, may be this article will help you to Install composer in system.

Here is the command to create a laravel project-

composer create-project --prefer-dist laravel/laravel blog

To start the development server of Laravel –

php artisan serve

URL: http://127.0.0.1:8000

Assuming laravel already installed inside your system.


Create Database & Connect

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE laravel_app;

To connect database with application, Open .env file from application root. Search for DB_ and update your details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=root

Install And Configure Laravel Passport

Laravel Passport package provides a full 0Auth2 server implementation for Laravel applications. By using it, we can easily generate a personal access token to uniquely identify a currently authenticated user. This token will then be attached to every request allowing each user access to protected routes. 

Open project into terminal and run this command.

$ composer require laravel/passport

After installation of package, it will create set of migration files which provides a scheme to store clients and access tokens

Next, we need to migrate file.

$ php artisan migrate

To create client tokens which needs to be generate for secured access tokens, run this given command

$ php artisan passport:install

Update User Model

When we install laravel setup, by default we get a model User.php inside /app/Models folder.

Open User.php and update by this code.

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens; // Add this line

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens;  // Add this HasApiTokens

    /**
     * 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',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

Update AuthServiceProvider File

Open AuthServiceProvider.php from /app/Providers folder and update by this piece of code.

<?php

namespace App\Providers;

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

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

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

        Passport::routes(); // Add this
    }
}

After registering Passport::routes(), Laravel Passport is almost ready to handle all authentication and authorization processes within laravel application.


Update auth Config File

Open auth.php from /config folder. Search for guards into that file and update it.

//...

'guards' => [
        
       //...
  
        'api' => [
            'driver' => 'passport', // set this to passport
            'provider' => 'users',
            'hash' => false,
        ],
    ],

//...

Create Model & Migration For Blog

Open project into terminal and run this artisan command.

$ php artisan make:model Blog -m

-m to create migration file as well.

Above command will generate two files. One is Model and second is migration file.

Model – Blog.php at /app/Models

Migration – 2021_03_20_040948_create_blogs_table.php at /database/migrations

Open Blog.php and write this code into it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'user_id', 'title', 'description'
    ];
}

Open Migration file 2021_03_20_040948_create_blogs_table.php and write this code.

<?php

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

class CreateBlogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->integer("user_id")->unsigned();
            $table->string("title", 80);
            $table->text("description");
        });
    }

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

Migration Migration

Back to terminal and run this command to create blogs table.

$ php artisan migrate

Create Controllers

Back to terminal and run these artisan commands to create.

Authentication Controller

$ php artisan make:controller API/AuthController

This command will create a file AuthController.php at /app/Http/Controllers/API. API is the folder which will be created to store API controller files.

Blog Controller

$ php artisan make:controller API/BlogController --api --model=Blog

This command will create a file BlogController.php file at /app/Http/Controllers/API folder.

Open AuthController.php and write this code.

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:55',
            'email' => 'email|required|unique:users',
            'password' => 'required|confirmed'
        ]);

        $validatedData['password'] = bcrypt($request->password);

        $user = User::create($validatedData);

        $accessToken = $user->createToken('authToken')->accessToken;

        return response([ 'user' => $user, 'access_token' => $accessToken]);
    }

    public function login(Request $request)
    {
        $loginData = $request->validate([
            'email' => 'email|required',
            'password' => 'required'
        ]);

        if (!auth()->attempt($loginData)) {
            return response(['message' => 'Invalid Credentials']);
        }

        $accessToken = auth()->user()->createToken('authToken')->accessToken;

        return response(['user' => auth()->user(), 'access_token' => $accessToken]);
    }
  
    public function profile()
    {
        $user_data = auth()->user();

        return response()->json([
            "status" => true,
            "message" => "User data",
            "data" => $user_data
        ]);
    }
  
    public function logout(Request $request)
    {
        // get token value
        $token = $request->user()->token();

        // revoke this token value
        $token->revoke();

        return response()->json([
            "status" => true,
            "message" => "User logged out successfully"
        ]);
    }
}

Open BlogController.php and write this code.

<?php

namespace App\Http\Controllers\API;

use App\Models\Blog;
use App\Http\Controllers\Controller;
use App\Http\Resources\BlogResource;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class BlogController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $blogs = Blog::all();
        return response([ 'blogs' => BlogResource::collection($blogs), 'message' => 'Retrieved successfully'], 200);
    }

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

        $validator = Validator::make($data, [
            'title' => 'required|max:80',
            'description' => 'required'
        ]);

        if($validator->fails()){
            return response(['error' => $validator->errors(), 'Validation Error']);
        }

        $user_id = auth()->user()->id;

        $data["user_id"] = $user_id;

        $blog = Blog::create($data);

        return response([ 'blog' => new BlogResource($blog), 'message' => 'Created successfully'], 200);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     */
    public function show(Blog $blog)
    {
        return response([ 'blog' => new BlogResource($blog), 'message' => 'Retrieved successfully'], 200);

    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Blog $blog)
    {

        $blog->update($request->all());

        return response([ 'blog' => new BlogResource($blog), 'message' => 'Retrieved successfully'], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param \App\Models\Blog $blog
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function destroy(Blog $blog)
    {
        $blog->delete();

        return response(['message' => 'Deleted']);
    }
}

Create Resource

Laravel Eloquent resources allow you to convert your models and collections into JSON format. 

Open terminal and write this command

$ php artisan make:resource BlogResource

It will create file BlogResource.php at location /app/Http/Resources.

Open BlogResource.php and write this code.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class BlogResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

Create API Routes

Open api.php from /routes folder. Add these routes into it.

// At header
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\BlogController;

Route::post('register', [AuthController::class, "register"]);
Route::post('login', [AuthController::class, "login"]);

Route::group(["middleware" => ["auth:api"]], function(){

    Route::get("profile", [AuthController::class, "profile"]);
    Route::post("logout", [AuthController::class, "logout"]);
});

Route::apiResource('blog', BlogController::class)->middleware('auth:api');

Open terminal and run this artisan command to see all available routes.

$ php artisan route:list

Application Testing

Run this command into project terminal to start development server,

php artisan serve

Register API – http://127.0.0.1:8000/api/register

Method – POST

{
"name": "Sanjay Kumar",
"email": "sanjay@gmail.com",
"password": "12345678",
"password_confirmation": "12345678"
}

Login API – http://127.0.0.1:8000/api/login

Method – POST

{
"email": "sanjay@gmail.com",
"password": "12345678"
}

Profile API – http://127.0.0.1:8000/api/profile

Method: GET

Header

Content-Type:application/json
Accept:application/json

Logout API – http://127.0.0.1:8000/api/logout

Method: POST

Header

Content-Type:application/json
Accept:application/json
Authorization: Bearer <Token>

Create Blog API – http://127.0.0.1:8000/api/blog

Method – POST

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Body

{
"title": "Blog 1",
"description": "Sample Blog content"
}

List All Blogs API – http://127.0.0.1:8000/api/blog

Method – GET

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Single Blog Detail API – http://127.0.0.1:8000/api/blog/1

Method – GET

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Update Blog API – http://127.0.0.1:8000/api/blog/1

Method – PATCH

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

Body

{
"name": "Blog Title updated",
"description": "New content for blog article"
}

Delete Blog API – http://127.0.0.1:8000/api/blog/1

Method – DELETE

Header

Content-Type:application/json
Authorization: Bearer <Token>
Accept:application/json

We hope this article helped you to learn about REST Api Development in Laravel 8 with Passport Tutorial in a very detailed way.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.