I hope everything is going well for you. I'm going to show you how to create a rest API in Laravel today. We'll build a restful API with Laravel 6 from the ground up. Rest APIs are increasingly widely used in web development.

Here, I'll show you how to use a passport to authenticate a rest API in a Laravel 7 application. In this tutorial, I'll teach you how to create restful api authentication in Laravel 7 using eloquent api resources. In Laravel 7, you can easily learn rest api for crud module with authentication.

When working with mobile applications, you must use the Rest API. If your programme is intended for both web and mobile platforms, you'll need to create an API for mobile development.

Laravel, on the other hand, makes it simple to create APIs. You can easily accomplish it with a passport if you have authentication in your mobile app. Passport in Laravel 7 provides a means to generate auth tokens for verifying users.

If you also want to create a rest API for your mobile app, you may follow this guide for step-by-step instructions on how to create a rest API with Laravel 7. If you're a beginner, don't worry; I'll walk you through this guide step by step.

This tutorial will teach you how to use the Laravel passport. That is, how to make use of the Laravel passport. I'll use Laravel passport for api authentication in this tutorial, and a simple e-commerce project to generate restful api crud. So, let's get started on our laravel rest api tutorial with a passport example.

Step 1: Install Laravel

I'll walk you through everything step by step. First, we'll create a new Laravel 6 application with the commands below. So, open a terminal OR a command prompt and type the following command:

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

Step 2: Setup Passport

In this stage, we'll use the Composer package management to install passport, so open a terminal and type the following command:

composer require laravel/passport

Following the successful installation of the package, we must obtain default migration in order to create new passport tables in our database. So, let's run the command below.

php artisan migrate

The next step is to use the command to install passport. It will generate token keys for security using the passport:install command. So, let's run the command below:

php artisan passport:install

Step 3: Passport Configuration

We must configure three things in this step: the model, the service provider, and the auth config file. So all you have to do now is keep track of the changes in that file.

The HasApiTokens class of Passport was added to the model.

Passport::routes() was added to AuthServiceProvider.

We added api auth configuration to auth.php

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\RegisterController@register');
Route::post('login', 'API\RegisterController@login');
Route::apiResource('/products','ProductController');
Route::group(['prefix' => 'products'],function() {
  Route::apiResource('/{product}/reviews','ReviewController');
});

Step 5: Create Model Migration and Controller and Factory

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

Open your migration table and put the code below into it.

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

We must now establish a link between the Product model and the Review model. To make it work, copy and paste the code into 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

Our database table and relationship are now complete. We can now run our migrate command to save that table in our database. So, after you've set up your database, run php artisan migrate and open it up.

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

});

Our factory setup is now complete. It's now time to add some dummy data. So, open your command prompt and paste the following command lines one after the other.

php artisan tinker

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

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

exit

We now have 50 products and 50 reviews for our products after running this command.

Step 9: Setup Product Controller

Now it's time to get the data for our API from the 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

Simply type the following commands to create a product resource and a review resource.

php artisan make:resource ProductCollection

php artisan make:resource ProductResouce 

php artisan make:resource ReviewResource

Following this command, three files will be added to the app/Http/Resources slug. Why did we build this resource or collection, for example? We can return our api data without this, but if you use Collection or Resource, you can adjust your return data. How did you do it? 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)
            ]
        ];
    }
}

As you can see, the name of our return data field contains information such as name, totalPrice, discount, and so on. You are free to use whatever name you choose. However, if you don't use it, you won't be able to update your outcome data. We may also add other field names to offer more information for a certain data. I hope you can see why we require a 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

For handling form data, Laravel provides a default Request. However, for a given model, we can utilise a custom request. To make a request, copy and paste the code below.

php artisan make:request Product

php artisan make:request Review

Now go to app/Http/Requests and you'll see two new files.

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

True or false is returned by the authorize() method. If true, it will only work for authenticated users; if false, it will work for all users. HTML form data was validated using the rules() method.

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

Everything for our rest api development project is now complete. So now you're ready to use Postman to run our Rest Api data. In Laravel, we are now able to operate a full restful api as well as a passport api. So, let's execute our example, so use the command below to run it quickly:

php artisan serve

Ensure that the following headers are used in the details api:

'headers' => [

    'Accept' => 'application/json',

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

]

I hope you will like the content and it will help you to learn How to Create REST API in Laravel7 using Passport
If you like this content, do share.


Recommended Posts

View All

Most Important Array Methods in JavaScript


Learn the most important array methods in JavaScript, including push, pop, shift, unshift, forEach, map, filter, reduce, and find. Improve your coding...

How to Install and Use MomentJS in Laravel 9 Application


Learn how to easily install and use MomentJS in your Laravel 9 application with our step-by-step guide. Improve your date and time management today!

Laravel Many to Many Polymorphic Relationship


Laravel many to many polymorphic relations, many to many polymorphic relations Laravel, polymorphic relations eloquent Laravel, Laravel morphToMany ex...

How to Install Ckeditor in Laravel 9


Laravel 9 ckeditor tutorial example, you will learn how to install or integrate ckeditor and use in laravel 9 app

How to Send SMS using Twilio in Laravel


Twilio shares cloud communications trends, customer tales, and advice for using Twilio's APIs to build scalable voice and SMS applications.