LARAVEL API CRUD Authenticate.

These are notes on how to create a laravel 8 app from scratch using CRUD. these steps will create a laravel project using SAIL.

Requirements:

  • PHP 7.4 or higher
  • Composer
  • Laravel 8
  • Postman/ Imsonmia for API Testing
  • Docker
  • Visual Code

This worked on an Ubuntu Linux Dev Envorinment.

create new project and run
$ cd /home/developer/Desktop/local-laravel/docker
$ ./docker_create_new_laravel

APP NAME: laravel-backend-api
 

// move into the project
$ cd laravel-backend-api

# Install And Configure Laravel Passport
$ composer require laravel/passport
$ sail artisan migrate
$ sail artisan passport:install

OUTPUT

Encryption keys generated successfully.
Personal access client created successfully.
Client ID: 1
Client secret: Sc73Rxxxx2joNAgsRt6iIW3PzrYmZDNMb4p
Password grant client created successfully.
Client ID: 2
Client secret: Jga3jBxxxxTc4Av9VwpQBT0HEv4wDk2o

Open User.php

$ code app/Models/User.php

ADD THIS LINE:
use Laravel\Passport\HasApiTokens;
CHANGE LINE TO:
use HasFactory, Notifiable,HasApiTokens;

Open AuthServiceProvider.php

$ code app/Providers/AuthServiceProvider.php

ADD:
use Laravel\Passport\Passport;
UNCOMMNET:
'App\Model' => 'App\Policies\ModelPolicy',
ADD AFTER $this->registerPolicies();
Passport::routes();

Add Passport’s TokenGuard

Open auth.php

$ code config/auth.php

UNDER 'api' CHANGE: 'driver' => 'token',
TO: 'driver' => 'passport',

create a CEO table

$ sail artisan make:model CEO -m

OPEN CEO MIGRATION FILE:
$ code database/migrations/*_create_c_e_o*.php

CHANGE THE up() METHOD TO THE FOLLOWING:

######################################################################
    public function up()
    {
        Schema::create('c_e_o_s', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('company_name');
            $table->year('year');
            $table->string('company_headquarters');
            $table->string('what_company_does');
            $table->timestamps();
        });
    }
######################################################################

OPEN CEO.php
$ code app/Models/CEO.php

ADD THE FOLLWOING INSIDE THE CEO FILE SHOULD LOOK LIKE THIS:

######################################################################
<?php

namespace App\Models;

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

class CEO extends Model
{
    use HasFactory;
    protected $fillable = [
        'name', 'company_name', 'year', 'company_headquarters', 'what_company_does'
    ];    
}
######################################################################

Make Migration:

$ sail php artisan migrate


OUTPUT:

Migrating: 2021_02_13_005605_create_c_e_o_s_table
Migrated:  2021_02_13_005605_create_c_e_o_s_table (47.69ms)



Now create controllers

- Authentication controller
$ sail artisan make:controller API/AuthController

OPEN AuthController.php and make it look like this:
$ code app/Http/Controllers/API/AuthController.php

######################################################################
<?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]);

    }
}

######################################################################

- Create CEO Controller

$ sail artisan make:controller API/CEOController --api --model=CEO

OPEN CEOController.php
$ code app/Http/Controllers/API/CEOController.php

MAKE IT LOOK LIKE THIS:

######################################################################
<?php

namespace App\Http\Controllers\API;

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

use Illuminate\Support\Facades\Validator;
use App\Http\Resources\CEOResource;

class CEOController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $ceos = CEO::all();
        return response([ 'ceos' => CEOResource::collection($ceos), '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, [
            'name' => 'required|max:255',
            'year' => 'required|max:255',
            'company_headquarters' => 'required|max:255',
            'what_company_does' => 'required'
        ]);

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

        $ceo = CEO::create($data);

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

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

    }

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

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

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

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

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


- Create a Resource

$ sail artisan make:resource CEOResource

OPEN CEOResource.php - NOTHING TO CHANGE. LEAVE AS IS
$ code app/Http/Resources/CEOResource.php

Setup the endpoints

Update Routes File
$ code routes/api.php
APPEND WITH:

######################################################################
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', 'App\Http\Controllers\API\AuthController@login');
Route::apiResource('/ceo', 'App\Http\Controllers\API\CEOController')->middleware('auth:api');
######################################################################

To view the entire list of the routes created for this application, run the following command from the terminal:
$ sail artisan route:list

TEST IN POSTMAN:

CREATE USER:
SETTINGS:
POST: http://localhost/api/register
body KEY: VALUE
name: cool
email: [email protected]
password: password123
password_confirmation: password123

LOGIN USER:
SETTINGS:
POST: http://localhost/api/login
body KEY: VALUE
email: [email protected]
password: password123

COPY THE TOKEN GIVEN FOR THE NEXT STEP:
[TOKEN]

Create CEO
SETTINGS:
POST: http://localhost/api/ceo
TOKEN: xxxxx
body:
name: Steve Jobs
year: 2021
company_headquarters: cupertino
what_company_does: phones
company_name: apple

Fetch the list of CEOs
SETTINGS:
GET: http://localhost/api/ceo
TOKEN: xxxxx

Show CEO
GET: http://localhost/api/ceo/1
TOKEN: xxxxx

Edit CEO
PATCH: http://localhost/api/ceo/1
TOKEN: xxxxx
body:
name: Jeff Besos
year: 2021
company_headquarters: seattle
what_company_does: ecommerce
company_name: AMAZON

Confirmed Edited CEO
GET: http://localhost/api/ceo/1
TOKEN: xxxxx

Delete CEO
DELETE: http://localhost/api/ceo/1
TOKEN: xxxxx

Confirm Deleted CEO
GET: http://localhost/api/ceo/1
TOKEN: xxxxx