Laravel 7 Rest Api Development with E-commerce Project

Hey Artisan

Hope you are doing well. Today i am going to show you laravel rest api development. We will develop restful api with laravel 6 from scratch. Rest api is now common thing in web development side.

Today i am going to show you rest api development with tiny e commerce project. We will development rest api with ecommerce project. I already create a tutorial on rest development with laravel passport authentication.

Read also : Laravel 6 REST API with Passport Tutorial with Ecommerce Project

But in this tutorial i will discuss about laravel 7 api tutorial. In this tutorial you will learn how to create laravel e commerce restful api from scratch. So if you don't know how to create laravel e commerce restful api, i will help you to learn.

But in this tutorial i will do rest api without passport authentication. Hope you will enjoy this rest api development in laravel 7 without passport tutorial. Let's start

laravel-rest-api-development

Now let's start our ecommerce Rest Api Development. 

Step 1 : Install Laravel 6

To do it run bellow command in your project directory.

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

 

Step 2: Create Route

In next step, we will add new two routes in api.php  file. One route for products and another for reviews.

routes\api.php

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

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

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

});

 

Step 3: Create Model Migration and Controller and Factory

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

 

Step 4: 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 5: 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 6: 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.

Read also : Laravel 6 : Building a REST API with Lumen

 

Step 7: 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 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)
    {   
        $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);
    }

 

Step 8: 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 9: Create Product 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

 

Read more : Laravel Cron Jobs and Task Scheduling Example From Scratch

 

app/Http/Requests/ProductRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProductRequest extends FormRequest
{
    
    public function authorize()
    {
        return false;
    }
  
    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 false;
    }
   
    public function rules()
    {
        return [
            "customer" => "required",
            "star" => "required|integer|between:0,5",
            "review" => "required"
        ];
    }
}

 

Step 10: 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.

http://127.0.0.1:8000/api/products

http://127.0.0.1:8000/api/products/4

http://127.0.0.1:8000/api/products/4/reviews

 

Read also : Laravel 6 REST API with JWT Authentication with CRUD

 

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.