Easy way in Creating an Image CRUD API with Laravel 8

Easy way in Creating an Image CRUD API with Laravel 8

Laravel is the most popular PHP framework for building backend application. It was created by Taylor Otwell in 2011 and it follows the MVC architecture pattern and it's based on Symfony (Symfony is also a PHP web application framework). One of the challenges face by beginners in building an API with any backend framework like Laravel, Django or NodeJS is dealing with file uploads such as videos or image. Database (MYSQL, POSTGRESQL, MONGODB etc) can only store text (JSON or CSV) and cannot store files such as image or videos. So where should such file (image or video) be stored? If we cannot store them in the database? Files such as Image or videos are not stored in the Database but are stored in the server itself, then the path of which the image or video is stored in the server is linked to the database in a form of text.

Screenshot (78).png Looking at the image above of a databased that store Ecommerce product the image columns is storing the path of the uploading Image in the server and not the image itself.

Storing Image in the server and linking it to the Database using Laravel 8

Storing Image on the server with laravel is not very complex because the framework itself is shipped with a lot of tools to assist with this unlike NodeJS that requires us to download a third party library such as multer, however we need to install a package call intervention using composer, this will allow the resizing of image upon upload.

I will proceed further with the assumption that we all know how to connect to our database in the .env file, create migrations, models and controllers.

In the ImageController.Php file

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image; /// image intervention 

class ImageController extends Controller
{
 public function store(Request $request)
    {
        // Validate incomming request
        $fields = $request->validate([
            'name'=>'required',
            'image'=>'required'
            'description'=>'required',

        ]);

   // Resizing and storing image in serve with the help of intervention 
            $file = $request->file('image'); / getting the image file from the incoming request
            $extention = $file->getClientOriginalExtension(); /getting the extension of the uploaded image     
            either jpg or png
            $filename =time().'.'.$extention; // creating a dynamic name to avoid duplication of name on the 
          server
          // resizing and storing the image inside a folder in our server
            Image::make($file)->resize(300, 200)->save('image/product/'. $filename, 100); 
       // storing the image path to the server in the database
        $product =Product::create([
             "name"=>$fields['name'],
            "description"=>$fields['description'],
            'image'=> 'image/product/'. $filename,
        ]);
        return response($product, 200); 
    }
}

Updating an image. To update an image is a little bit tricky because we want the new image to override the old one, we do not want to store the old image and new image together, we therefore need to write a code that delete the old image before uploading the new one. The following code below can solve the challenge of deleting old image and uploading new updated image

public function update(Request $request, $id)
    {
// simple incoming request validation
        $fields = $request->validate([
            'name'=>'required',
            'image'=>'required',
            'description'=>'required',

        ]);

// this block of code stays the same with image upload
            $file = $request->file('image');
            $extention = $file->getClientOriginalExtension();
            $filename =time().'.'.$extention;
            Image::make($file)->resize(300, 200)->save('image/product/'. $filename, 100); 
            $product =Product::find($id);  //we find the product we want to update by id

// these four lines of code below is very crucial , we check for old image and we call Laravel’s unlink to delete the old image from the server before updating with new image
            $old_img =$product->image;
            if($old_img){
                unlink($old_img);
            }  
            $product->update([
             "name"=>$fields['name'],
            "description"=>$fields['description'],
            'image'=> 'image/product/'. $filename,
        ]);


        return response($product, 200); 

    }

From the code above we deleted the old image first then create an update with the new one.

Deleting an image is very simple compared to updating. First we use the unlink to delete the file from the server then delete the path stored in the database Check the code below

 public function destroy($id)
    {
     $product =Product::find($id);
     $old_img = $product->image;
     unlink($old_img);

     Product::find($id)->delete();

        return response("Product Deleted", 204);
    }

To show single product and read product

public function show($id)
    {
     $product = Product::find($id);
     return response($product, 200);
    }
  public function index()
    {
        $product = Product::all();
        return $product;
    }