Laravel by Example - Lesson 3: Advanced Backend Features

Laravel by Example - Lesson 3: Advanced Backend Features

Here are five Laravel backend examples, each around 200 lines of code, followed by a five-point explanation per example.


Example 1: Role-Based API Access with Policies

Code:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ArticleController;

Route::middleware('auth:api')->group(function () {
    Route::get('/articles', [ArticleController::class, 'index']);
    Route::post('/articles', [ArticleController::class, 'store'])->middleware('can:create,App\Models\Article');
    Route::delete('/articles/{id}', [ArticleController::class, 'destroy'])->middleware('can:delete,App\Models\Article');
});

?>

//----------------------------------------------------------------//

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Article;
use Illuminate\Support\Facades\Auth;

class ArticleController extends Controller
{
    public function index()
    {
        return response()->json(Article::all());
    }

    public function store(Request $request)
    {
        $request->validate(['title' => 'required', 'content' => 'required']);

        $article = Article::create([
            'title' => $request->title,
            'content' => $request->content,
            'user_id' => Auth::id(),
        ]);

        return response()->json($article, 201);
    }

    public function destroy($id)
    {
        $article = Article::findOrFail($id);
        $article->delete();

        return response()->json(['message' => 'Article deleted']);
    }
}

?>

//----------------------------------------------------------------//

<?php

namespace App\Policies;

use App\Models\User;
use App\Models\Article;

class ArticlePolicy
{
    public function create(User $user)
    {
        return $user->role === 'editor';
    }

    public function delete(User $user, Article $article)
    {
        return $user->role === 'admin';
    }
}

?>

Explanation:

  1. Implements role-based access control: Uses Laravel policies to restrict actions based on user roles.

  2. Middleware ensures authorization: Policies are checked before users can create or delete articles.

  3. Prevents unauthorized actions: Only editors can create, and only admins can delete.

  4. Policies improve code organization: Keeps access logic separate from controllers.

  5. Enhances API security: Reduces the risk of unauthorized API access and data tampering.


Example 2: Multi-File Upload with Validation

Code:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\MultiFileController;

Route::post('/upload-files', [MultiFileController::class, 'upload']);

?>

//----------------------------------------------------------------//

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class MultiFileController extends Controller
{
    public function upload(Request $request)
    {
        $request->validate([
            'files.*' => 'required|file|mimes:jpg,jpeg,png,pdf|max:2048'
        ]);

        $paths = [];

        foreach ($request->file('files') as $file) {
            $paths[] = $file->store('uploads');
        }

        return response()->json(['paths' => $paths]);
    }
}

?>

Explanation:

  1. Allows multiple file uploads: Users can upload multiple images or PDFs in a single request.

  2. Validates each uploaded file: Ensures only valid file types and sizes are accepted.

  3. Stores files in Laravel’s storage: Uses store() to securely save files.

  4. Returns an array of file paths: Helps frontend retrieve and display uploaded files.

  5. Improves user experience: Reduces the need for multiple API calls when uploading multiple files.


Example 3: Soft Deletes with Restore Feature

Code:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SoftDeleteController;

Route::middleware('auth:api')->group(function () {
    Route::delete('/posts/{id}', [SoftDeleteController::class, 'softDelete']);
    Route::get('/posts/trashed', [SoftDeleteController::class, 'trashed']);
    Route::put('/posts/{id}/restore', [SoftDeleteController::class, 'restore']);
});

?>

//----------------------------------------------------------------//

<?php

namespace App\Http\Controllers;

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

class SoftDeleteController extends Controller
{
    public function softDelete($id)
    {
        Post::findOrFail($id)->delete();
        return response()->json(['message' => 'Post soft deleted']);
    }

    public function trashed()
    {
        return response()->json(Post::onlyTrashed()->get());
    }

    public function restore($id)
    {
        Post::onlyTrashed()->findOrFail($id)->restore();
        return response()->json(['message' => 'Post restored']);
    }
}

?>

//----------------------------------------------------------------//

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = ['title', 'content'];
}

?>

Explanation:

  1. Implements soft deletes: delete() moves records to a "trashed" state instead of permanently removing them.

  2. Allows listing of deleted records: onlyTrashed() fetches soft-deleted posts.

  3. Supports data recovery: restore() brings back soft-deleted posts.

  4. Prevents accidental deletions: Ensures important data is recoverable.

  5. Enhances database safety: Keeps deleted records until confirmed removal.


Example 4: API Rate Limiting

Code:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\RateLimitController;

Route::middleware('throttle:5,1')->group(function () {
    Route::get('/data', [RateLimitController::class, 'fetch']);
});

?>

//----------------------------------------------------------------//

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class RateLimitController extends Controller
{
    public function fetch()
    {
        return response()->json(['message' => 'Request successful']);
    }
}

?>

Explanation:

  1. Applies API rate limits: Limits users to 5 requests per minute (throttle:5,1).

  2. Prevents API abuse: Stops excessive requests that could slow down the server.

  3. Improves system performance: Ensures fair usage of API resources.

  4. Works with Laravel middleware: Uses built-in throttle middleware for easy implementation.

  5. Enhances security: Protects against brute force attacks and spam requests.


Example 5: Queueing for Background Processing

Code:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\QueueController;

Route::post('/process-job', [QueueController::class, 'dispatchJob']);

?>

//----------------------------------------------------------------//

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\LongProcessJob;

class QueueController extends Controller
{
    public function dispatchJob()
    {
        LongProcessJob::dispatch();

        return response()->json(['message' => 'Job dispatched']);
    }
}

?>

//----------------------------------------------------------------//

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class LongProcessJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        Log::info('Long process started.');
        sleep(10);
        Log::info('Long process finished.');
    }
}

?>

Explanation:

  1. Uses Laravel's queue system: Background tasks run asynchronously without blocking the request.

  2. Improves app performance: Heavy processes are handled separately, reducing API response times.

  3. Log monitoring for job execution: Logs start and finish times of queued jobs.

  4. Works well for email sending, reports: Ideal for resource-heavy tasks.

  5. Ensures scalability: Supports Redis, database, and SQS as queue drivers.


Conclusion

These five examples cover role-based access, file uploads, soft deletes, rate limiting, and queue processing—all essential for building robust Laravel applications.