Laravel

How to Build a Laravel 12 REST API for Product Management

Laravel 12 REST API for Product Management with Full CRUD Support

Laravel is a powerful PHP framework that simplifies modern web development. In this tutorial, we’ll guide you through building a RESTful Product Management API in Laravel 12, fully updated for Laravel’s new minimalist structure.

We’ll use:

  • Laravel 12
  • MySQL database
  • php artisan install:api
  • REST API principles
  • Postman for testing

✨ Features

  • Retrieve Products: Fetch all or a specific product.
  • Create Products: Add new products.
  • Update Products: Modify existing product data.
  • Delete Products: Remove product records.

🚀 Step 1: Create Laravel 12 Project

composer create-project laravel/laravel laravel12-rest-api
cd laravel12-rest-api

⚙️ Step 2: Set Up API Structure (Laravel 12+)

Since Laravel 12 uses a minimal skeleton:

php artisan install:api

This command generates:

  • routes/api.php
  • Middleware registration in bootstrap/app.php

📁 bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(
    basePath: dirname(__DIR__)
)
->withRouting(
    web: __DIR__ . '/../routes/web.php',
    api: __DIR__ . '/../routes/api.php',
    commands: __DIR__ . '/../routes/console.php',
    health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
    // Register middleware here
})
->withExceptions(function (Exceptions $exceptions) {
    // Handle exceptions here
})
->create();

💡 Step 4: Create the Product Model and Migration

php artisan make:model Product -m

Update the generated migration file in database/migrations/:

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description');
        $table->decimal('price', 10, 2);
        $table->timestamps();
    });
}

Then run:

php artisan migrate

🖊️ Step 5: Create the ProductController

php artisan make:controller ProductController --resource

Update app/Http/Controllers/ProductController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index()
    {
        return response()->json(Product::all(), 200);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'required|string',
            'price' => 'required|numeric|min:0',
        ]);

        $product = Product::create($validated);
        return response()->json($product, 201);
    }

    public function show($id)
    {
        $product = Product::find($id);

        if (!$product) {
            return response()->json(['message' => 'Product not found'], 404);
        }

        return response()->json($product);
    }

    public function update(Request $request, $id)
    {
        $product = Product::find($id);

        if (!$product) {
            return response()->json(['message' => 'Product not found'], 404);
        }

        $validated = $request->validate([
            'name' => 'sometimes|required|string|max:255',
            'description' => 'sometimes|required|string',
            'price' => 'sometimes|required|numeric|min:0',
        ]);

        $product->update($validated);
        return response()->json($product);
    }

    public function destroy($id)
    {
        $product = Product::find($id);

        if (!$product) {
            return response()->json(['message' => 'Product not found'], 404);
        }

        $product->delete();
        return response()->json(['message' => 'Product deleted successfully']);
    }
}

🚪 Step 6: Define API Routes

Open routes/api.php and add:

use App\Http\Controllers\ProductController;

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

✍️ Step 7: Allow Mass Assignment in the Product Model

Update app/Models/Product.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Product extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'description', 'price'];
}

🚪 Step 8: Test API Endpoints

Use Postman or curl to test:

1. Get All Products

  • Method: GET
  • URL: http://localhost:8000/api/products

2. Create Product

  • Method: POST
  • URL: http://localhost:8000/api/products
  • Body:
{
  "name": "Laptop",
  "description": "A high-performance laptop",
  "price": 1500.00
}

3. Get a Specific Product

  • Method: GET
  • URL: http://localhost:8000/api/products/{id}

4. Update a Product

  • Method: PUT
  • URL: http://localhost:8000/api/products/{id}
  • Body:
{
  "name": "Gaming Laptop",
  "price": 1800.00
}

5. Delete a Product

  • Method: DELETE
  • URL: http://localhost:8000/api/products/{id}

🔐 Laravel 12 REST API with Sanctum Authentication (Extended CRUD)

In this tutorial, we’ll extend our Laravel 12 Product CRUD API to use Laravel Sanctum for secure token-based authentication. This lets you protect routes and only allow authenticated users to manage products.

📦 Requirements

  • Laravel 12
  • MySQL database
  • Laravel Sanctum package
  • Postman (for API testing)

🛠️ Step 1: Install Sanctum

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

⚙️ Step 2: Register Sanctum Middleware

Open bootstrap/app.php and add inside withMiddleware():

$middleware->alias([
    'auth:sanctum' => \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
]);

👤 Step 3: Update User Model

In app/Models/User.php:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    // ...
}

🧑‍💻 Step 4: Create AuthController

php artisan make:controller AuthController

Then update app/Http/Controllers/AuthController.php:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => 'required|confirmed|min:6',
        ]);

        $user = User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
        ]);

        $token = $user->createToken('api-token')->plainTextToken;

        return response()->json(['user' => $user, 'token' => $token], 201);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required'
        ]);

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        $token = $user->createToken('api-token')->plainTextToken;

        return response()->json(['user' => $user, 'token' => $token]);
    }

    public function logout(Request $request)
    {
        $request->user()->tokens()->delete();
        return response()->json(['message' => 'Logged out successfully']);
    }
}

🛣️ Step 5: Register Auth & Protected Routes

In routes/api.php:

use App\Http\Controllers\AuthController;
use App\Http\Controllers\ProductController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);

Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::apiResource('products', ProductController::class);
});

🧪 Step 6: Test with Postman

1️⃣ Register

  • Method: POST
  • URL: http://localhost:8000/api/register
{
  "name": "Umar",
  "email": "umar@example.com",
  "password": "secret123",
  "password_confirmation": "secret123"
}

2️⃣ Login

  • Method: POST
  • URL: http://localhost:8000/api/login
{
  "email": "umar@example.com",
  "password": "secret123"
}

3️⃣ Use Token in Header

In all protected requests (CRUD):

Authorization: Bearer YOUR_TOKEN_HERE

4️⃣ Access Product Routes

  • GET /api/products
  • POST /api/products
  • PUT /api/products/{id}
  • DELETE /api/products/{id}

✅ Summary

  • ✅ Laravel 12 Product CRUD API implemented
  • ✅ Sanctum authentication integrated
  • ✅ Protected routes using auth:sanctum
  • ✅ Token-based access via Postman

Now your Laravel 12 REST API is secure and production-ready with authentication!

Leave a Reply

Your email address will not be published. Required fields are marked *