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 8 from scratch. Rest api is now common thing in web development side.
Sometimes we need to create api for our product or sometings else from our web application. In this application i will help you and teach you that how we can create api with laravel passport authenticantion. I will teach you from step by step so that you can learn laravel passport and laravel rest api development better.
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
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.
#restful-api #rest-api #api-development #laravel-6 #laravel