How to QuickStart Secured Rest API Project With Laravel 9 ?
Tags: laravel, programming, tutorial, webdev
Published: 2022-05-28 07:51:56

## Make REST API in LARAVEL 9

Today I am going to explain how you can make REST API in Laravel 9. In this video i am going to explain about CRUD Operation using REST API.

## Laravel 9 Installation.
After [Installing Laravel 9](https://dev.to/shanisingh03/how-to-install-laravel-9-25c4) we will open the code in Editor.

## Step - 1
Create a Model `Post` with migration.

```php
php artisan make:model Post -m
```
Next Update The Migration file at `database/migrations` folder.

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->longText('description');
            $table->timestamps();
        });
    }

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

```
Next update the Model fillable property in `app/models/Post.php`

```php
<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

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

```

## Step - 2
Now Generate controller by running command
```php
php artisan make:controller Api\\PostController --model=Post
```
this command will generate the file in `app/Http/Controllers/Api/PostController.php`

Open the file and update the code below.
```php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\StorePostRequest;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::all();

        return response()->json([
            'status' => true,
            'posts' => $posts
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

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

        return response()->json([
            'status' => true,
            'message' => "Post Created successfully!",
            'post' => $post
        ], 200);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(StorePostRequest $request, Post $post)
    {
        $post->update($request->all());

        return response()->json([
            'status' => true,
            'message' => "Post Updated successfully!",
            'post' => $post
        ], 200);
    }

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

        return response()->json([
            'status' => true,
            'message' => "Post Deleted successfully!",
        ], 200);
    }
}
```

## Step - 3
Now Let's create the request to validate the data by running command below.
```php
php artisan make:request StorePostRequest
```

Now open file from `app/Http/Requests/StorePostRequest.php` and update the code below.

```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            "title" => "required|max:70",
            "description" => "required"
        ];
    }
}
```

## Step - 4
Now create the API routes in `routes/api.php` 

```php
<?php

use App\Http\Controllers\Api\PostController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;


Route::apiResource('posts', PostController::class);

```

Now serve the application and open the URL in postman.
The results will look like.


![Get POSTS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8r3vfimiyhn7hk5loxw4.png)

![Store Post](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zu9lvdy0u0c9at730t2j.png)


![Update Post](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfxbjk1rvlo4u3znukct.png)


![Delete Post](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqkbxyxfmptkxojrjg95.png)

## Make REST API AUTHENTICATION in LARAVEL 9 USING LARAVEL SANCTUM

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs.

## Installation Steps
If you are not using LARAVEL 9 you need to install LARAVEL Sanctum Otherwise you can skip the installation step.

### Step 1
Install via composer

```php
composer require laravel/sanctum
```
### Step 2
Publish the Sanctum Service Provider

```php
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
```

### Step 3
Migrate The Database
```php
php artisan migrate
```

## USING SANCTUM IN LARAVEL

### User `HasApiTokens` Trait in `App\Models\User`

In Order to use Sanctum we need to use `HasApiTokens` Trait Class in User Model.
User Model should look like.
```php
<?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\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

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

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}
```
### API Authentication Routes

Create `AuthController` to handle all authentication realted to API
```php
php artisan make:controller Api\\AuthController
```

In `routes\api.php` file update the API

```php
Route::post('/auth/register', [AuthController::class, 'createUser']);
Route::post('/auth/login', [AuthController::class, 'loginUser']);
```

Now update `AuthContoller` with
```php
<?php

namespace App\Http\Controllers\Api;

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

class AuthController extends Controller
{
    /**
     * Create User
     * @param Request $request
     * @return User 
     */
    public function createUser(Request $request)
    {
        try {
            //Validated
            $validateUser = Validator::make($request->all(), 
            [
                'name' => 'required',
                'email' => 'required|email|unique:users,email',
                'password' => 'required'
            ]);
    
            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make($request->password)
            ]);

            return response()->json([
                'status' => true,
                'message' => 'User Created Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);
            
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Login The User
     * @param Request $request
     * @return User
     */
    public function loginUser(Request $request)
    {
        try {
            $validateUser = Validator::make($request->all(), 
            [
                'email' => 'required|email',
                'password' => 'required'
            ]);
    
            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

            if(!Auth::attempt($request->only(['email', 'password']))){
                return response()->json([
                    'status' => false,
                    'message' => 'Email & Password does not match with our record.',
                ], 401);
            }

            $user = User::where('email', $request->email)->first();

            return response()->json([
                'status' => true,
                'message' => 'User Logged In Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);

        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
}
```

### Protect API With Authentication we need to use `auth:sanctum` middleware.

```php
Route::apiResource('posts', PostController::class)->middleware('auth:sanctum');
```

Here are the results.

![Register User](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3payp41pzmr2lcuuuvx.png)

![Login API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/685yuqku1c8mz1xcaimc.png)

![GET API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up6yc28lo9j3vccl5r7y.png)

The complete Tutorial is below in the video.

{% youtube FZL-T2gu-XA %}

If you face any issue while making REST API, please comment your query.

Thank You for Reading

Reach Out To me.
[Twitter](https://twitter.com/shanisingh03)
[Instagram](https://www.instagram.com/shanisingh03/)
[TechToolIndia YouTube Channel](https://www.youtube.com/channel/UCOy6o08Yn9DtXMKqxhD9ivA)