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

Eloquent with JSON Data Columns Tutorial in Laravel 11

Blade Template Tutorial Three Template Inheritance in Laravel 11