Laravel 6 REST API and Passport Tutorial (with an eCommerce Project)

Laravel 6 REST API and Passport Tutorial (with an eCommerce Project)

In this tutorial, we’ll explore the ways you can build—and test—a robust API using Laravel. We’ll be using Laravel 6, and all of the code is available for reference on GitHub. Now we are going to develop a ecommerce rest api where we have a product table and a review table. Using those two table we will make our ecommerce rest api.

Rest Api Development

In this tutorial, we’ll explore the ways you can build—and test—a robust API using Laravel. We’ll be using Laravel 6, and all of the code is available for reference on GitHub. Now we are going to develop a ecommerce rest api where we have a product table and a review table. Using those two table we will make our ecommerce rest api.

RESTful APIs

First, we need to understand what exactly is considered a RESTful API. REST stands for REpresentational State Transfer and is an architectural style for network communication between applications, which relies on a stateless protocol (usually HTTP) for interaction.

HTTP Verbs Represent Actions

In RESTful APIs, we use the HTTP verbs as actions, and the endpoints are the resources acted upon. We’ll be using the HTTP verbs for their semantic meaning:

  • **GET: **retrieve resources
  • POST: create resources
  • PUT: update resources
  • **DELETE: **delete resources

Update Action: PUT vs. POST

RESTful APIs are a matter of much debate and there are plenty of opinions out there on whether is best to update with POST, PATCH, or PUT, or if the create action is best left to the PUT verb. In this article we’ll be using PUT for the update action, as according to the HTTP RFC, PUT means to create/update a resource at a specific location. Another requirement for the PUT verb is idempotence, which in this case basically means you can send that request 1, 2 or 1000 times and the result will be the same: one updated resource in the database

Here, i will tech you how to create rest api with authentication using passport in laravel 6 application. i will show you step by step build restful api authentication using eloquent api resources in laravel 6. you can easily learn rest api for crud module with authentication in laravel 6.

Rest API is must be use when you are working with mobile application. when your application is prefer for web app and mobile app than you must have to create api for your mobile development.

However, Laravel provide easy way to create api. if you have authentication in your mobile app than you can easily do it using passport. Laravel 6 Passport provide way to create auth token for validating users.

So you also want to create rest api for your mobile application than you can follow this tutorial for how to create rest api step by step with laravel 6. If you are new than don't worry about that i written tutorial step by step.

Step 1: Install Laravel 6

I am going to explain step by step from scratch so, we need to get fresh Laravel 6 application using bellow command, So open your terminal OR command prompt and run bellow command:

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

Step 2: Setup Passport

In this step we need to install passport via the Composer package manager, so one your terminal and fire bellow command:

composer require laravel/passport

After successfully install package, we require to get default migration for create new passport tables in our database. so let's run bellow command.

php artisan migrate

Next, we need to install passport using command, Using passport:install command, it will create token keys for security. So let's run bellow command:

php artisan passport:install

Step 3: Passport Configuration

In this step, we have to configuration on three place model, service provider and auth config file. So you have to just following change on that file.

In model we added HasApiTokens class of Passport,
In AuthServiceProvider we added "Passport::routes()",
In auth.php, we added api auth configuration.

app/User.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;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

app/Providers/AuthServiceProvider.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
{

    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    public function boot()
    {
        $this->registerPolicies();
    }
}

config/auth.php

return [
    .....
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
    .....
]

Step 4: Create API Routes

Route::post('register', 'API\[email protected]');
Route::post('login', 'API\[email protected]');

Route::apiResource('/products','ProductController');

Route::group(['prefix' => 'products'],function(){

  Route::apiResource('/{product}/reviews','ReviewController');

});

Step 5: Create Model Migration and Controller and Factory

in next step, now we have create new controller as BaseController,and RegisterController, i created new folder "API" in Controllers folder because we will make alone APIs controller, So let's create controller: We need two table for this Rest Api and also we will create two factory for creating our dummy data. So run bellow command to make those things.

php artisan make:model Product -fmr
php artisan make:model Review -fmr

app/Http/Controllers/API/BaseController.php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;

class BaseController extends Controller
{

    public function sendResponse($result, $message)
    {
    	$response = [
            'success' => true,
            'data'    => $result,
            'message' => $message,
        ];

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

    public function sendError($error, $errorMessages = [], $code = 404)
    {
    	$response = [
            'success' => false,
            'message' => $error,
        ];

        if(!empty($errorMessages)){
            $response['data'] = $errorMessages;
        }

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

app/Http/Controllers/API/RegisterController.php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;

class RegisterController extends BaseController
{

    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()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

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

        return $this->sendResponse($success, 'User register successfully.');
    }

    public function login(Request $request)
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 
            $user = Auth::user(); 
            $success['token'] =  $user->createToken('MyApp')-> accessToken; 
            $success['name'] =  $user->name;

            return $this->sendResponse($success, 'User login successfully.');
        } 
        else{ 
            return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
        } 
    }
}

Step 6: Setup database table

Now open your migration table and paste the below code.

database/migrations/products.php

Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->text('detail');
            $table->double('price');
            $table->string('stock');
            $table->double('discount');
            $table->integer('user_id')->unsigned();
            $table->timestamps();
});

database/migrations/reviews.php

Schema::create('reviews', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('product_id');
            $table->string('customer');
            $table->text('review');
            $table->double('star');
            $table->timestamps();
});

Step 7: Make relationship between product and review

Now we have to make relationship between Product model and Review model. for making it paste those code to your product and review model.

app/Product.php

namespace App;

use App\Review;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{   
	protected $fillable = [
        'name', 'detail', 'stock','price','discount'
    ];
    public function reviews()
    {
    	return $this->hasMany(Review::class);
    }
}

app/Review.php

namespace App;

use App\Product;
use Illuminate\Database\Eloquent\Model;

class Review extends Model
{   
	protected $fillable = [
        'customer', 'star', 'review'
    ];
    public function product()
    {
    	return $this->belongsTo(Product::class);
    }
}

Step 8: Setup factory

Now our relationship and and our database table is ready. so now we can run our migrate command to save that table in our database**. **So after configuring your database run **php artisan migrate **and open

database/factory/ProductFactory.php

use Faker\Generator as Faker;

$factory->define(Product::class, function (Faker $faker) {
    return [
        "name" => $faker->word,
        "detail" => $faker->paragraph,
        "price" => $faker->numberBetween(100,1000),
        "stock" => $faker->randomDigit,
        "discount" => $faker->numberBetween(2,30),
        "user_id" => function(){
        	return \App\User::all()->random();
        }
    ];
});

database/factory/ReviewFactory.php

use Faker\Generator as Faker;

$factory->define(Review::class, function (Faker $faker) {

    return [
    	"product_id" => function(){
    		return App\Product::all()->random();
    	},
        "customer" => $faker->name,
        "review" => $faker->paragraph,
        "star" => $faker->numberBetween(0,5)
    ];

});

Now our factory setup is done. So time to insert some dummy data. So open your command and paste this following line of command one after another.

php artisan tinker

factory(\App\Product::class,50)->create()

factory(\App\Review::class,50)->create()

exit

After running this command we have 50 product and 50 reviews for our products.

Step 9: Setup Product Controller

Now time to fetch our api data from database. So open

app\Http\Controllers\ProductController.php

namespace App\Http\Controllers;
use App\Http\Requests\ProductRequest;
use App\Http\Resources\ProductCollection;
use App\Http\Resources\ProductResource;
use App\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends Controller
{   

    public function __construct()
    {
        $this->middleware('auth:api')->except('index','show');
    }

    public function index()
    {

        return ProductCollection::collection(Product::paginate(5));
    }

    public function store(ProductRequest $request)
    {
       $product = new Product;
       $product->name = $request->name;
       $product->detail = $request->description;
       $product->price = $request->price;
       $product->stock = $request->stock;
       $product->discount = $request->discount;

       $product->save();

       return response([

         'data' => new ProductResource($product)

       ],Response::HTTP_CREATED);

    }

    public function show(Product $product)
    {
        return new ProductResource($product);
    }

    public function update(Request $request, Product $product)
    {   
        $this->userAuthorize($product);

        $request['detail'] = $request->description;

        unset($request['description']);

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

       return response([

         'data' => new ProductResource($product)

       ],Response::HTTP_CREATED);

    }

    public function destroy(Product $product)
    {
        $product->delete();

        return response(null,Response::HTTP_NO_CONTENT);
    }

     public function userAuthorize($product)
    {
        if(Auth::user()->id != $product->user_id){
            //throw your exception text here;

        }
    }
}

Step 10: Create Resource Collection

For creating product resource and review resource just enter the following commands.

php artisan make:resource ProductCollection

php artisan make:resource ProductResouce 

php artisan make:resource ReviewResource

After running this command you will get three file to app/Http/Resources slug. Look , why we create this resource or collection ? Without creating this we can return our api data, But if you use Collection or Resource then you can modify your return data. How ? Look

app/Http/Resources/ProductCollection.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ProductCollection extends Resource {

    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'totalPrice' => round((1-($this->discount/100)) * $this->price,2),
            'discount' => $this->discount,
            'rating' => $this->reviews->count() > 0 ? round($this->reviews->sum('star')/$this->reviews->count(),2) : 'No rating yet',
            'href' => [
               'link' => route('products.show',$this->id)
            ]
        ];
    }
}

Now see we put name, totalPrice, **discount **etc in our return data field name. Here you can use any name whatever you want. But if you don't use it then you can't change your outcome data. Also we can add extra field name to show more information for a particular data. Hope you understand why we need resource or collection.

app/Http/Resources/ProductResource.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ProductResource extends Resource
{

    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'description' => $this->detail,
            'price' => $this->price,
            'stock' => $this->stock == 0 ? 'Out of stock' : $this->stock,
            'discount' => $this->discount,
            'totalPrice' => round((1-($this->discount/100)) * $this->price,2),
            'rating' => $this->reviews->count() > 0 ? round($this->reviews->sum('star')/$this->reviews->count(),2) : 'No rating yet',
            'href' => [
               'reviews' => route('reviews.index',$this->id)
            ]
        ];
    }
}

app/Http/Resources/ReviewResource.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ReviewResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'customer' => $this->customer,
            'body' => $this->review,
            'star' => $this->star,
       ];
    }
}

Step 11: Create Custom Request

Laravel gives us default Request for handle form data. But we can use custom request for a specific model. Paste this following code to make request.

php artisan make:request Product

php artisan make:request Review

Now visit app/Http/Requests you will get two newly created file

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProductRequest extends FormRequest
{

    public function authorize()
    {
        return true; //Only authorize user can do this operation if false then unauthorize user can do
    }

    public function rules()
    {
        return [
            'name' => 'required|max:255|unique:products',
            'description' => 'required',
            'price' => 'required|max:10',
            'stock' => 'required|max:6',
            'discount' => 'required|max:2'
        ];
    }
}

**authorize() **method return two things, true or false. If true then it will work for only authenticated user and if false it will works for unauthorize user. **rules() **method validated html form data.

app/Http/Requests/ReviewRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ReviewRequest extends FormRequest
{

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            "customer" => "required",
            "star" => "required|integer|between:0,5",
            "review" => "required"
        ];
    }
}

**Step 12: Setup review **controller

app/Http/Controllers/ReviewController.php

namespace App\Http\Controllers;

use App\Http\Resources\ReviewResource;
use App\Product;
use App\Review;
use Illuminate\Http\Request;

class ReviewController extends Controller
{
    public function index(Product $product)
    {
       return ReviewResource::collection($product->reviews);

    }

    public function store(ReviewRequest $request , Product $product)
    {
       $review = new Review($request->all());

       $product->reviews()->save($review);

       return response([
         'data' => new ReviewResource($review)
       ],Response::HTTP_CREATED);
    }

    public function update(Request $request, Product $procduct, Review $review)
    {
        $review->update($request->all());
    }

    public function destroy(Product $product, Review $review)
    {
        $review->delete();
        return response(null,Response::HTTP_NO_CONTENT);
    }
}

Now everything is done for our rest api development project. So now you are ready to run our Rest Api data in your postman. Now we are ready to to run full restful api and also passport api in laravel. so let's run our example so run bellow command for quick run:

php artisan serve

make sure in details api we will use following headers as listed bellow:

'headers' => [

    'Accept' => 'application/json',

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

]

Here is Routes URL with Verb:

Register API: Verb:GET, URL:http://localhost:8000/api/register
Login API: Verb:GET, URL:http://localhost:8000/api/login
Product API: URL:http://127.0.0.1:8000/api/products
Product Single API: URL:http://127.0.0.1:8000/api/products/4
Product Review API: URL:http://127.0.0.1:8000/api/products/4/reviews

Now visit those url in your postman and you will see your api data. Hope you've enjoy this tutorial. If you have any doubt or confusion then ask me you confution in the comment box. i will try to fix your confusion. Hope it can help you.

How to create REST API with authentication using Passport in Laravel 6

How to create REST API with authentication using Passport in Laravel 6

In this tutorial, you'll learn how to create rest api with authentication using passport in laravel 6 application. I will show you step by step build Restful API Authentication using eloquent API resources in Laravel 6.

REST API is must be use when you are working with mobile application. when your application is prefer for web app and mobile app than you must have to create api for your mobile development.

However, Laravel provide easy way to create api. if you have authentication in your mobile app than you can easily do it using passport. Laravel 6 Passport provide way to create auth token for validating users.

So you also want to create rest api for your mobile application than you can follow this tutorial for how to create rest api step by step with Laravel 6. If you are new than don't worry about that i written tutorial step by step.

Step 1: Install Laravel 6

I am going to explain step by step from scratch so, we need to get fresh Laravel 6 application using bellow command, So open your terminal OR command prompt and run bellow command:

composer create-project --prefer-dist laravel/laravel blog
Step 2: Use Passport

In this step we need to install passport via the Composer package manager, so one your terminal and fire bellow command:

composer require laravel/passport

After successfully install package, we require to get default migration for create new passport tables in our database. so let's run bellow command.

php artisan migrate

Next, we need to install passport using command, Using passport:install command, it will create token keys for security. So let's run bellow command:

php artisan passport:install

Read Also: Laravel 6 CRUD Application Tutorial

Step 3: Passport Configuration

In this step, we have to configuration on three place model, service provider and auth config file. So you have to just following change on that file.

In model we added HasApiTokens class of Passport,

In AuthServiceProvider we added "Passport::routes()",

In auth.php, we added api auth configuration.

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',

    ];

}

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();

    }

}

config/auth.php

<?php


return [

    .....

    'guards' => [

        'web' => [

            'driver' => 'session',

            'provider' => 'users',

        ],

        'api' => [

            'driver' => 'passport',

            'provider' => 'users',

        ],

    ],

    .....

]
Step 4: Add Product Table and Model

Next, we require to create migration for posts table using Laravel 6 php artisan command, so first fire bellow command:

php artisan make:migration create_products_table

After this command you will find one file in following path database/migrations and you have to put bellow code in your migration file for create products table.

<?php


use Illuminate\Support\Facades\Schema;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;


class CreateProductsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::create('products', function (Blueprint $table) {

            $table->bigIncrements('id');

            $table->string('name');

            $table->text('detail');

            $table->timestamps();

        });

    }


    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::dropIfExists('products');

    }

}

After create migration we need to run above migration by following command:

php artisan migrate

After create "products" table you should create Product model for products, so first create file in this path app/Product.php and put bellow content in item.php file:

app/Product.php

<?php

  

namespace App;

   

use Illuminate\Database\Eloquent\Model;

   

class Product extends Model

{

    /**

     * The attributes that are mass assignable.

     *

     * @var array

     */

    protected $fillable = [

        'name', 'detail'

    ];

}
Step 5: Create API Routes

In this step, we will create api routes. Laravel provide api.php file for write web services route. So, let's add new route on that file.

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\[email protected]');

Route::post('login', 'API\[email protected]');

   

Route::middleware('auth:api')->group( function () {

    Route::resource('products', 'API\ProductController');

});
Step 6: Create Controller Files

in next step, now we have create new controller as BaseController, ProductController and RegisterController, i created new folder "API" in Controllers folder because we will make alone APIs controller, So let's create both controller:

app/Http/Controllers/API/BaseController.php

<?php


namespace App\Http\Controllers\API;


use Illuminate\Http\Request;

use App\Http\Controllers\Controller as Controller;


class BaseController extends Controller

{

    /**

     * success response method.

     *

     * @return \Illuminate\Http\Response

     */

    public function sendResponse($result, $message)

    {

    	$response = [

            'success' => true,

            'data'    => $result,

            'message' => $message,

        ];


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

    }


    /**

     * return error response.

     *

     * @return \Illuminate\Http\Response

     */

    public function sendError($error, $errorMessages = [], $code = 404)

    {

    	$response = [

            'success' => false,

            'message' => $error,

        ];


        if(!empty($errorMessages)){

            $response['data'] = $errorMessages;

        }


        return response()->json($response, $code);

    }

}

app/Http/Controllers/API/RegisterController.php

<?php

   

namespace App\Http\Controllers\API;

   

use Illuminate\Http\Request;

use App\Http\Controllers\API\BaseController as BaseController;

use App\User;

use Illuminate\Support\Facades\Auth;

use Validator;

   

class RegisterController extends BaseController

{

    /**

     * 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()){

            return $this->sendError('Validation Error.', $validator->errors());       

        }

   

        $input = $request->all();

        $input['password'] = bcrypt($input['password']);

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

        $success['token'] =  $user->createToken('MyApp')->accessToken;

        $success['name'] =  $user->name;

   

        return $this->sendResponse($success, 'User register successfully.');

    }

   

    /**

     * Login api

     *

     * @return \Illuminate\Http\Response

     */

    public function login(Request $request)

    {

        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ 

            $user = Auth::user(); 

            $success['token'] =  $user->createToken('MyApp')-> accessToken; 

            $success['name'] =  $user->name;

   

            return $this->sendResponse($success, 'User login successfully.');

        } 

        else{ 

            return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);

        } 

    }

}

app/Http/Controllers/API/ProductController.php

<?php

   

namespace App\Http\Controllers\API;

   

use Illuminate\Http\Request;

use App\Http\Controllers\API\BaseController as BaseController;

use App\Product;

use Validator;

use App\Http\Resources\Product as ProductResource;

   

class ProductController extends BaseController

{

    /**

     * Display a listing of the resource.

     *

     * @return \Illuminate\Http\Response

     */

    public function index()

    {

        $products = Product::all();

    

        return $this->sendResponse(ProductResource::collection($products), 'Products retrieved successfully.');

    }

    /**

     * 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',

            'detail' => 'required'

        ]);

   

        if($validator->fails()){

            return $this->sendError('Validation Error.', $validator->errors());       

        }

   

        $product = Product::create($input);

   

        return $this->sendResponse(new ProductResource($product), 'Product created successfully.');

    } 

   

    /**

     * Display the specified resource.

     *

     * @param  int  $id

     * @return \Illuminate\Http\Response

     */

    public function show($id)

    {

        $product = Product::find($id);

  

        if (is_null($product)) {

            return $this->sendError('Product not found.');

        }

   

        return $this->sendResponse(new ProductResource($product), 'Product retrieved successfully.');

    }

    

    /**

     * Update the specified resource in storage.

     *

     * @param  \Illuminate\Http\Request  $request

     * @param  int  $id

     * @return \Illuminate\Http\Response

     */

    public function update(Request $request, Product $product)

    {

        $input = $request->all();

   

        $validator = Validator::make($input, [

            'name' => 'required',

            'detail' => 'required'

        ]);

   

        if($validator->fails()){

            return $this->sendError('Validation Error.', $validator->errors());       

        }

   

        $product->name = $input['name'];

        $product->detail = $input['detail'];

        $product->save();

   

        return $this->sendResponse(new ProductResource($product), 'Product updated successfully.');

    }

   

    /**

     * Remove the specified resource from storage.

     *

     * @param  int  $id

     * @return \Illuminate\Http\Response

     */

    public function destroy(Product $product)

    {

        $product->delete();

   

        return $this->sendResponse([], 'Product deleted successfully.');

    }

}
Step 7: Create Eloquent API Resources

This is a very important step of creating rest api in laravel 6. you can use eloquent api resources with api. it will helps you to make same response layout of your model object. we used in ProductController file. now we have to create it using following command:

php artisan make:resource Product

Now there created new file with new folder on following path:

app/Http/Resources/Product.php

<?php

  

namespace App\Http\Resources;

   

use Illuminate\Http\Resources\Json\JsonResource;

   

class Product extends JsonResource

{

    /**

     * Transform the resource into an array.

     *

     * @param  \Illuminate\Http\Request  $request

     * @return array

     */

    public function toArray($request)

    {

        return [

            'id' => $this->id,

            'name' => $this->name,

            'detail' => $this->detail,

            'created_at' => $this->created_at->format('d/m/Y'),

            'updated_at' => $this->updated_at->format('d/m/Y'),

        ];

    }

}

Now we are ready to to run full restful api and also passport api in laravel. so let's run our example so run bellow command for quick run:

php artisan serve

make sure in details api we will use following headers as listed bellow:

'headers' => [

    'Accept' => 'application/json',

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

]

Here is Routes URL with Verb:

Now simply you can run above listed url like as bellow screen shot:

  1. Register API: Verb:GET, URL:http://localhost:8000/api/register

  1. Login API: Verb:GET, URL:http://localhost:8000/api/login

  1. Product List API: Verb:GET, URL:http://localhost:8000/api/products

  1. Product Create API: Verb:POST, URL:http://localhost:8000/api/products

  1. Product Show API: Verb:GET, URL:http://localhost:8000/api/products/{id}

  1. Product Update API: Verb:PUT, URL:http://localhost:8000/api/products/{id}

  1. Product Delete API: Verb:DELETE, URL:http://localhost:8000/api/products/{id}

You can download code from git: Download Code from Github

I hope it can help you...

Developing RESTful APIs with Lumen (A PHP Micro-framework)

Developing RESTful APIs with Lumen (A PHP Micro-framework)

In this tutorial, I’ll show you how easy it is to build and secure an API with Lumen. Lumen is a PHP micro-framework built to deliver micro-services and blazing fast APIs. Learn how to build and secure RESTful APIs with Lumen

In this tutorial, I’ll show you how easy it is to build and secure an API with Lumen. Lumen is a PHP micro-framework built to deliver micro-services and blazing fast APIs. Learn how to build and secure RESTful APIs with Lumen

Lumen is an open-source PHP based micro-framework created by Taylor Otwell in 2015. Lumen is designed for building lightning fast micro-services and APIs. And it opts for maximum speed rather than flexibility in the bootstrapping process. The PHP micro-framework was born out of the need to have light Laravel installations that could be faster than existing PHP micro-frameworks such as Slim and Silex.

Lumen Features And Architecture

Lumen utilizes the Illuminate components that power the Laravel framework. One amazing thing about the way Lumen was built is the fact that you can painlessly upgrade right into Laravel. One of such scenarios where an upgrade process is applicable is when you discover that you need more features out of the box that Lumen doesn’t offer.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

The entire bootstrap process is located in a single file.

Lumen Key Requirements

In order to use Lumen, you need to have the following tools installed on your machine.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

Note: You’ll need MySQL for this tutorial. Navigate to the mysql website and install the community server edition. If you are using a Mac, I’ll recommend following these instructions. To avoid micromanaging from the terminal, I’ll also recommend installing a MySQL GUI, Sequel Pro.## Building a Fast Authors API Rapidly With Lumen

At Auth0, we have a number of technical writers, otherwise known as authors. A directive has been given to developing an app to manage Auth0 authors. The frontend app will be built with ReactJS. However, it needs to pull data from a source and also push to it. Yes, we need an API!

This is what we need the API to do:

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

Let’s flesh out the possible endpoints for this API. Given some authors resource, we’ll have the following endpoints:

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

What will be the author attributes? Let’s flesh it out like we did the endpoints.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

Install Lumen

Run the following command in your terminal to create a new project with Lumen:

composer create-project --prefer-dist laravel/lumen authors


cd into the newly created project.

cd authors


Now, run php -S localhost:8000 -t public to serve the project. Head over to your browser. You should see the index page like so:

Authors Index

Activate Eloquent and Facades

As I mentioned earlier, the entire bootstrap process is located in a single file. Open up the bootstrap/app.php and uncomment this line, // app->withEloquent. Once uncommented, Lumen hooks the Eloquent ORM with your database as configured in the .env file.

Note: You’ll need MySQL for this tutorial. Navigate to the mysql website and install the community server edition. If you are using a Mac, I’ll recommend following these instructions. To avoid micromanaging from the terminal, I’ll also recommend installing a MySQL GUI, Sequel Pro.
In addition uncomment this line //$app->withFacades(); . Once uncommented, we can make use of Facades in our project.

Setup Database, Models and Migrations

At the time of this writing, Lumen supports four database systems: MySQL, Postgres, SQLite, and SQL Server. We are making use of MySQL in this tutorial. First, we’ll create a migration for the Authors table.

Note: You’ll need MySQL for this tutorial. Navigate to the mysql website and install the community server edition. If you are using a Mac, I’ll recommend following these instructions. To avoid micromanaging from the terminal, I’ll also recommend installing a MySQL GUI, Sequel Pro.
Run the command below in the terminal to create the Authors table migration:

php artisan make:migration create_authors_table


The new migration will be placed in your database/migrations directory. Each migration file name contains a timestamp which allows Lumen to determine the order of the migrations. Next, we’ll modify the recently created migration to accommodate the Authors attributes.

Open up the migration file and modify it like so:

<?php

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

class CreateAuthorsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('authors', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email');
            $table->string('github');
            $table->string('twitter');
            $table->string('location');
            $table->string('latest_article_published');
            $table->timestamps();
        });
    }

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


In the code above, we added the columns to the authors table.

Now, go ahead and run the migration like so:

php artisan migrate


Check your database. You should have the authors and migrations table present.

Let’s create the Author model. Create an app/Author.php file and add the code below to it:

app/Author.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Author extends Model
{

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

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [];
}


In the code above, we made the author attributes mass assignable.

Set up Routes

Routing is straight-forward. Open up routes/web.php and modify it like so:

<?php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/

$router->get('/', function () use ($router) {
    return $router->app->version();
});

$router->group(['prefix' => 'api'], function () use ($router) {
  $router->get('authors',  ['uses' => '[email protected]']);

  $router->get('authors/{id}', ['uses' => '[email protected]']);

  $router->post('authors', ['uses' => '[email protected]']);

  $router->delete('authors/{id}', ['uses' => '[email protected]']);

  $router->put('authors/{id}', ['uses' => '[email protected]']);
});


In the code above, we have abstracted the functionality for each route into a controller, AuthorController. Route groups allow you to share route attributes, such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual route. Therefore, every route will have a prefix of /api. Next, let’s create the Author Controller.

Set up Author Controller

Create a new file, AuthorController.php in app/Http/Controllers directory and add the following code to it like so:

<?php

namespace App\Http\Controllers;

use App\Author;
use Illuminate\Http\Request;

class AuthorController extends Controller
{

    public function showAllAuthors()
    {
        return response()->json(Author::all());
    }

    public function showOneAuthor($id)
    {
        return response()->json(Author::find($id));
    }

    public function create(Request $request)
    {
        $author = Author::create($request->all());

        return response()->json($author, 201);
    }

    public function update($id, Request $request)
    {
        $author = Author::findOrFail($id);
        $author->update($request->all());

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

    public function delete($id)
    {
        Author::findOrFail($id)->delete();
        return response('Deleted Successfully', 200);
    }
}


Let’s analyze the code above. First, we required the Author model, use App\Author. Moving forward, we invoked the necessary methods from the Author model for each controller method. We have five methods here. showAllAuthors, showOneAuthor, create, update and delete.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

For example, if you make a POST request to /api/authors API endpoint, the create function will be invoked.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

Finally, test the API routes with Postman.

Author GET operation

Author POST operation

Author PUT operation

Author DELETE operation

Our API works. Awesome!

Lumen API Validation

When developing applications, never trust the user. Always validate incoming data. In Lumen, it’s very easy to validate your application’s incoming data. Lumen provides access to the $this->validate helper method from within Route closures.

Open up the AuthorController file and add modify the create method like so:

...
 public function create(Request $request)
    {
        $this->validate($request, [
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'location' => 'required|alpha'
        ]);

        $author = Author::create($request->all());

        return response()->json($author, 201);
    }
...


Test the API POST route with Postman.

It validated the incoming requests and returned the appropriate error message.

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

Note: You’ll need MySQL for this tutorial. Navigate to the mysql website and install the community server edition. If you are using a Mac, I’ll recommend following these instructions. To avoid micromanaging from the terminal, I’ll also recommend installing a MySQL GUI, Sequel Pro.
Check out a plethora of validation rules that you can use with Lumen.

Securing the Authors API with Auth0

Right now, anyone can make GET and POST requests to all of the endpoints present in our API. In a real-world scenario, we should restrict POST, DELETE and PUT requests to certain registered and authorized users.

We’ll go ahead and secure some of these API endpoints with JSON Web Tokens.

JSON Web Tokens, commonly known as JWTs, are tokens that are used to authenticate users on applications. This technology has gained popularity over the past few years because it enables backends to accept requests simply by validating the contents of these JWTs. That is, applications that use JWTs no longer have to hold cookies or other session data about their users. This characteristic facilitates scalability while keeping applications secure.

Whenever the user wants to access a protected route or resource (an endpoint), the user agent must send the JWT, usually in the Authorization header using the Bearer schema, along with the request.

When the API receives a request with a JWT, the first thing it does is to validate the token. This consists of a series of steps, and if any of these fails then, the request must be rejected. The following list shows the validation steps needed:

  • Routing: Lumen provides routing out of the box via Fast Route. Fast Route is a library that provides a fast implementation of a regular expression based router.
  • Authentication: Lumen does not support session state. However, incoming requests are authenticated via a stateless mechanism such as tokens.
  • Caching: Lumen supports caching just like Laravel. In fact, there are no differences between using the cache in Lumen and Laravel. Cache drivers such as Database, Memcached, and Redis are supported. You will need to install the illuminate/redis package via Composer before using a Redis cache with Lumen.
  • Errors and Logging: Lumen ships with the Monolog library, which provides support for various log handlers.
  • Queuing: Lumen provides a queuing service that is similar to Laravel’s. It provides a unified API across a variety of different queue back-ends.
  • Events: Lumen’s events provide a simple observer implementation, allowing you to subscribe and listen for events in your application.

We will make use of Auth0 to issue our JSON Web Tokens. With Auth0, we have to write just a few lines of code to get a solid identity management solution, including single sign-on, user management, support for social identity providers (like Facebook, GitHub, Twitter, etc.), enterprise (Active Directory, LDAP, SAML, etc.), and your own database of users.

For starters, if you haven’t done so yet, this is a good time to sign up for a free Auth0 account. Having an Auth0 account, the first thing that we must do is to create a new API on the dashboard. An API is an entity that represents an external resource, capable of accepting and responding to protected resource requests made by clients.

Note: You’ll need MySQL for this tutorial. Navigate to the mysql website and install the community server edition. If you are using a Mac, I’ll recommend following these instructions. To avoid micromanaging from the terminal, I’ll also recommend installing a MySQL GUI, Sequel Pro.
Login to your Auth0 management dashboard and create a new API client.

Click on the APIs menu item and then the Create API button. You will need to give your API a name and an identifier. The name can be anything you choose, so make it as descriptive as you want.

The identifier will be used to identify your API, this field cannot be changed once set. For our example, I’ll name the API, Authors API, and for the identifier, I’ll set it as https://authorsapi.com. We’ll leave the signing algorithm as RS256 and click on the Create API button.

Create a New API

Creating the Authors API

You can define scopes in this section

Head over to your terminal and install Auth0 PHP SDK:

composer require auth0/auth0-php:~5.0


Create a new middleware file, Auth0Middleware.php in the app/Http/Middleware directory. Add the following code to it like so:

<?php

namespace App\Http\Middleware;

use Closure;
use Auth0\SDK\JWTVerifier;

class Auth0Middleware
{
    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(!$request->hasHeader('Authorization')) {
          return response()->json('Authorization Header not found', 401);
        }

        $token = $request->bearerToken();

        if($request->header('Authorization') == null || $token == null) {
          return response()->json('No token provided', 401);
        }

        $this->retrieveAndValidateToken($token);

        return $next($request);
    }

    public function retrieveAndValidateToken($token)
    {
        try {
            $verifier = new JWTVerifier([
              'supported_algs' => ['RS256'],
              'valid_audiences' => ['AUTH0_API_AUDIENCE'],
              'authorized_iss' => ['AUTH0_DOMAIN']
            ]);

            $decoded = $verifier->verifyAndDecode($token);
        }
        catch(\Auth0\SDK\Exception\CoreException $e) {
            throw $e;
        };
    }

}


In the retrieveAndValidateToken method, we created an instance of JWTVerifier to verify the token coming from the Authorization header. It checks the algorithm, the API audience, and the issuer to ensure the token is a valid one issued by Auth0.

Note: Replace the AUTH0_API_AUDIENCE and AUTH0_DOMAIN placeholders with the API audience and Auth0 domain values from your Auth0 dashboard.

Now, we want to assign the newly created middleware to our routes. The first step is to assign the middleware a short-hand key in bootstrap/app.php file’s call to the $app->routeMiddleware() method.

Go ahead and open up bootstrap/app.php and uncomment this line of code:

...
// $app->routeMiddleware([
//     'auth' => App\Http\Middleware\Authenticate::class,
// ]);
...


Once uncommented, replace the Authenticate::class with Auth0Middleware::class like so:

$app->routeMiddleware([
    'auth' => App\Http\Middleware\Auth0Middleware::class,
]);


Once the middleware has been defined in the HTTP kernel, as we have done above. We can now use the middleware key in the route options array in the routes/web.php file like so:

...
$router->group(['prefix' => 'api', 'middleware' => 'auth'], function () use ($router) {
  $router->get('authors',  ['uses' => '[email protected]']);

  $router->get('authors/{id}', ['uses' => '[email protected]']);

  $router->post('authors', ['uses' => '[email protected]']);

  $router->delete('authors/{id}', ['uses' => '[email protected]']);

  $router->put('authors/{id}', ['uses' => '[email protected]']);
});


We just secured all the API endpoints with JWT. If a user accesses these API endpoint/route without a valid access token or no token at all, it returns an error. Try it out.

Accessing any endpoint without an authorization header

Accessing any endpoint without any token provided

Accessing any endpoint without a valid access token

Now, let’s test it with a valid access token. Head over to the test tab of your newly created API on your Auth0 dashboard.

Grab the Access token from the Test tab

Grab the Access Token

Now use this access token in Postman by sending it as an Authorization header to make a POST request to api/people endpoint.

Accessing the endpoint securely

It validates the access token and successfully makes the POST request.

Wondering how to integrate the secure API with a frontend? Check out our amazing React and Vue.js authentication tutorials.

Conclusion

Well done! You have learned how to build and secure a rest API with the powerful PHP micro-framework, Lumen, and JWT. Need to use PHP to build your API or micro-service? I’d bet on Lumen as the tool of choice for speed and ease of use.

Check out the repo to get the code.

Build RESTful API In Laravel 5.8 Example

Build RESTful API In Laravel 5.8 Example

In this tutorial, i will explain you how to create rest api in laravel 5.8 application. we will use passport for api authentication. we will create register and login api with product crud api.

In this tutorial, i will explain you how to create rest api in laravel 5.8 application. we will use passport for api authentication. we will create register and login api with product crud api.

If you want to create web services with php than i will must suggest to use laravel 5.8 to create apis because laravel provide structure with authentication using passport. Based on structure it will become a very easily way to create rest apis.

Just Few days ago, laravel released it's new version as laravel 5.8. As we know laravel is a more popular because of security feature. So many of the developer choose laravel to create rest api for mobile app developing. Yes Web services is a very important when you create web and mobile developing, because you can create same database and work with same data.

Follow bellow few steps to create restful api example in laravel 5.8 app.

Step 1: Download Laravel 5.8

I am going to explain step by step from scratch so, we need to get fresh Laravel 5.8 application using bellow command, So open your terminal OR command prompt and run bellow command:

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

Step 2: Install Passport

In this step we need to install passport via the Composer package manager, so one your terminal and fire bellow command:

composer require laravel/passport

After successfully install package, we require to get default migration for create new passport tables in our database. so let's run bellow command.

php artisan migrate

Next, we need to install passport using command, Using passport:install command, it will create token keys for security. So let's run bellow command:

php artisan passport:install

Step 3: Passport Configuration

In this step, we have to configuration on three place model, service provider and auth config file. So you have to just following change on that file.

In model we added HasApiTokens class of Passport,

In AuthServiceProvider we added "Passport::routes()",

In auth.php, we added api auth configuration.

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

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();
    }
}

config/auth.php

<?php

return [
    .....
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
    .....
]

Step 4: Add Product Table and Model

next, we require to create migration for posts table using Laravel 5.8 php artisan command, so first fire bellow command:

php artisan make:migration create_products_table

After this command you will find one file in following path database/migrations and you have to put bellow code in your migration file for create products table.

<?php

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

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

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

After create migration we need to run above migration by following command:

php artisan migrate

After create "products" table you should create Product model for products, so first create file in this path app/Product.php and put bellow content in item.php file:

app/Product.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

Step 5: Create API Routes

In this step, we will create api routes. Laravel provide api.php file for write web services route. So, let's add new route on that file.

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\[email protected]');
  
Route::middleware('auth:api')->group( function () {
	Route::resource('products', 'API\ProductController');
});

Step 6: Create Controller Files

in next step, now we have create new controller as BaseController, ProductController and RegisterController, i created new folder "API" in Controllers folder because we will make alone APIs controller, So let's create both controller:

app/Http/Controllers/API/BaseController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;

class BaseController extends Controller
{
    /**
     * success response method.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendResponse($result, $message)
    {
    	$response = [
            'success' => true,
            'data'    => $result,
            'message' => $message,
        ];

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

    /**
     * return error response.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendError($error, $errorMessages = [], $code = 404)
    {
    	$response = [
            'success' => false,
            'message' => $error,
        ];

        if(!empty($errorMessages)){
            $response['data'] = $errorMessages;
        }

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

app/Http/Controllers/API/ProductController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Product;
use Validator;

class ProductController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $products = Product::all();

        return $this->sendResponse($products->toArray(), 'Products retrieved successfully.');
    }

    /**
     * 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',
            'detail' => 'required'
        ]);

        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

        $product = Product::create($input);

        return $this->sendResponse($product->toArray(), 'Product created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $product = Product::find($id);

        if (is_null($product)) {
            return $this->sendError('Product not found.');
        }

        return $this->sendResponse($product->toArray(), 'Product retrieved successfully.');
    }

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

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

        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

        $product->name = $input['name'];
        $product->detail = $input['detail'];
        $product->save();

        return $this->sendResponse($product->toArray(), 'Product updated successfully.');
    }

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

        return $this->sendResponse($product->toArray(), 'Product deleted successfully.');
    }
}

app/Http/Controllers/API/RegisterController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;

class RegisterController extends BaseController
{
    /**
     * 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()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

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

        return $this->sendResponse($success, 'User register successfully.');
    }
}

Now we are ready to to run full restful api and also passport api in laravel. so let's run our example so run bellow command for quick run:

php artisan serve

make sure in details api we will use following headers as listed bellow:

'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer '.$accessToken,
]

Here is Routes URL with Verb:

  1. Login: Verb:GET, URL:http://localhost:8000/oauth/token

  2. Register: Verb:GET, URL:http://localhost:8000/api/register

  3. List: Verb:GET, URL:http://localhost:8000/api/products

  4. Create: Verb:POST, URL:http://localhost:8000/api/products

  5. Show: Verb:GET, URL:http://localhost:8000/api/products/{id}

  6. Update: Verb:PUT, URL:http://localhost:8000/api/products/{id}

  7. Delete: Verb:DELETE, URL:http://localhost:8000/api/products/{id}

Now simply you can run above listed url like as bellow screen shot:

Login API:

Register API:

Product List API:

Product Create API:

Product Show API:

Product Update API:

Product Delete API:

I hope it can help you...

Thanks for reading ❤

If you liked this post, share it with all of your programming buddies!