API CRUD Tutorial in Laravel 11

 <?php


namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class AuthController extends Controller
{
    public function signup(Request $request)
    {
        // make() method is used to validate form data which is got from "Request" class
        // Validator::make() method provides extra functionality to check fails() or success() as shown below :
        $validateUser = Validator::make(
            $request->all(),
            [
                "name" => "required",
                "email" => "required|email|unique:users,email",
                "password" => "required"
            ]
        );

        if ($validateUser->fails()) {
            return response()->json([
                "status" => false,
                "message" => "Validation Error",
                "errors" => $validateUser->errors()->all()
            ], 401);
        }

        $user = User::create([
            "name" => $request->name,
            "email" => $request->email,
            "password" => $request->password
        ]);

        return response()->json([
            "status" => true,
            "message" => "User Created Successfully",
            "user" => $user
        ], 200);
    }

    public function login(Request $request)
    {
        $validateUser = Validator::make(
            $request->all(),
            [
                "email" => "required|email",
                "password" => "required"
            ]
        );

        if ($validateUser->fails()) {
            return response()->json([
                "status" => false,
                "message" => "Authentication Fails",
                "errors" => $validateUser->errors()->all()
            ], 404);
        }

        if (Auth::attempt(["email" => $request->email, "password" => $request->password])) {
            $authUser = Auth::user();
            return response()->json([
                "status" => true,
                "message" => "User Logged in Successfully",
                "token" => $authUser->createToken("API Token")->plainTextToken,
                "token_type" => "bearer"
            ], 200);
        } else {
            return response()->json([
                "status" => false,
                "message" => "Email & Password does not matched."
            ], 401);
        }
    }

    public function logout(Request $request)
    {
        $user = $request->user();
        $user->tokens()->delete();  //Here, delete all tokens from database of particular user

        return response()->json([
            "status" => true,
            "user" => $user,
            "message" => "You logged out successfully.",
        ], 200);
    }
}
Above File is app\Http\Controllers\API\AuthController.php File




Below File is app\Http\Controllers\API\BaseController.php File
<?php

namespace App\Http\Controllers\API;

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

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, $errorMessage = [], $code = 404)
    {
        $response = [
            "success" => false,
            "message" => $error
        ];

        if (!empty($errorMessage)) {
            $response["data"] = $errorMessage;
        }

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





Below File is app\Http\Controllers\API\PostController.php File
<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\API\BaseController as BaseController;

class PostController extends BaseController
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $data["posts"] = Post::all();

        // 1st way we can written as shown below :
        // return response()->json([
        //     "status" => true,
        //     "message" => "All Post Data.",
        //     "data" => $data
        // ], 200);

        // 2nd way we can written as shown below :
        return $this->sendResponse($data, "All Post Data.");
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        // make() method is used to validate form data which is got from "Request" class
        // Validator::make() method provides extra functionality to check fails() or success() as shown below :
        $validateUser = Validator::make(
            $request->all(),
            [
                "title" => "required",
                "description" => "required",
                "image" => "required|mimes:png,jpg,jpeg,gif"
            ]
        );

        if ($validateUser->fails()) {
            // 1st way we can written as shown below :
            // return response()->json([
            //     "status" => false,
            //     "message" => "Validation Error",
            //     "errors" => $validateUser->errors()->all()
            // ], 401);

            // 2nd way we can written as shown below :
            return $this->sendError("Validation Error", $validateUser->errors()->all());
        }

        $img = $request->image;
        $ext = $img->getClientOriginalExtension();
        $imageName = time() . "." . $ext;
        $img->move(public_path() . "/uploads/", $imageName);

        $post = Post::create([
            "title" => $request->title,
            "description" => $request->description,
            "image" => $imageName
        ]);

        // 1st way we can written as shown below :
        // return response()->json([
        //     "status" => true,
        //     "message" => "Post Created Successfully",
        //     "post" => $post
        // ], 200);

        // 2nd way we can written as shown below :
        return $this->sendResponse($post, "Post Created Successfully");
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $data["post"] = Post::select(
            "id",
            "title",
            "description",
            "image"
        )->where(["id" => $id])->get();

        // 1st way we can written as shown below :
        // return response()->json([
        //     "status" => true,
        //     "message" => "Your Single Post",
        //     "data" => $data
        // ], 200);

        // 2nd way we can written as shown below :
        return $this->sendResponse($data, "Your Single Post");
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        $validateUser = Validator::make(
            $request->all(),
            [
                "title" => "required",
                "description" => "required",
                "image" => "required|mimes:png,jpg,jpeg,gif"
            ]
        );

        if ($validateUser->fails()) {
            // 1st way we can written as shown below :
            // return response()->json([
            //     "status" => false,
            //     "message" => "Validation Error",
            //     "errors" => $validateUser->errors()->all()
            // ], 401);

            // 2nd way we can written as shown below :
            return $this->sendError("Validation Error", $validateUser->errors()->all());
        }

        $postImage = Post::select("id", "image")->where(["id" => $id])->get();

        if ($request->image != "") {
            $path = public_path() . "/uploads/";

            if ($postImage[0]->image != "" && $postImage[0]->image != null) {
                $old_file = $path . $postImage[0]->image;
                if (file_exists($old_file)) {
                    unlink($old_file);
                }
            }

            $img = $request->image;
            $ext = $img->getClientOriginalExtension();
            $imageName = time() . "." . $ext;
            $img->move(public_path() . "/uploads/", $imageName);
        } else {
            $imageName = $postImage->image;
        }

        $post = Post::where(["id" => $id])->update([
            "title" => $request->title,
            "description" => $request->description,
            "image" => $imageName
        ]);

        // 1st way we can written as shown below :
        // return response()->json([
        //     "status" => true,
        //     "message" => "Post Updated Successfully",
        //     "post" => $post
        // ], 200);

        // 2nd way we can written as shown below :
        return $this->sendResponse($post, "Post Updated Successfully");
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        $imagePath = Post::select("image")->where("id", $id)->get();

        $filePath = public_path() . "/uploads/" . $imagePath[0]["image"];

        unlink($filePath);

        $post = Post::where("id", $id)->delete();

        // 1st way we can written as shown below :
        // return response()->json([
        //     "status" => true,
        //     "message" => "Your Post has been removed.",
        //     "post" => $post,
        // ], 200);

        // 2nd way we can written as shown below :
        return $this->sendResponse($post, "Your Post has been removed.");
    }
}





Below File is app\Models\Post.php File
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public $timestamps = "true";
    protected $table = "posts";
    protected $fillable = ["title", "description", "image"];
}





Below File is app\Models\User.php File
<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, HasApiTokens;
    public $timestamps = true;
    protected $table = "users";

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}





Below File is database\migrations\2024_12_30_101545_create_users_table File
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string("name");
            $table->string("email", 100)->unique();
            $table->string("password");
            $table->timestamps();
        });
    }

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





Below File is database\migrations\2024_12_30_101822_create_posts_table File
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string("title");
            $table->text("description");
            $table->string("image");
            $table->timestamps();
        });
    }

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





Below File is database\migrations\2024_12_30_102401_create_personal_access_tokens_table File
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('personal_access_tokens', function (Blueprint $table) {
            $table->id();
            $table->string('tokenable_type', 191); // Limit length to fit within MySQL index size
            $table->unsignedBigInteger('tokenable_id'); // Use unsigned big integer for ID
            $table->index(['tokenable_type', 'tokenable_id']); // Explicitly create the index
            $table->string('name');
            $table->string('token', 64)->unique();
            $table->text('abilities')->nullable();
            $table->timestamp('last_used_at')->nullable();
            $table->timestamp('expires_at')->nullable();
            $table->timestamps();
        });
    }

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





Below File is routes\api.php File
<?php

use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\PostController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');

Route::controller(AuthController::class)->group(function () {
    Route::post("signup", "signup");
    Route::post("login", "login");
});

Route::middleware("auth:sanctum")->group(function () {
    Route::post("logout", [AuthController::class, "logout"]);
    Route::apiResource("posts", PostController::class);
});





Below File is routes\web.php File
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});













Comments

Popular posts from this blog

Eloquent Many to Many Relationship Tutorial in Laravel 11

Blade Template Tutorial Three Template Inheritance in Laravel 11