Lumen by Example - Lesson 3

Lumen by Example - Lesson 3


Example 1: Role-Based Access Control (RBAC) API

Allows different users (Admin, User) to access different endpoints.

File: routes/web.php

$router->group(['middleware' => 'auth'], function () use ($router) {
    $router->get('/admin', ['middleware' => 'role:admin', 'uses' => 'AdminController@index']);
    $router->get('/user', ['middleware' => 'role:user', 'uses' => 'UserController@index']);
});

File: app/Http/Middleware/RoleMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RoleMiddleware {
    public function handle(Request $request, Closure $next, $role) {
        if ($request->user()->role !== $role) {
            return response()->json(['error' => 'Access Denied'], 403);
        }
        return $next($request);
    }
}

File: app/Http/Controllers/AdminController.php

<?php

namespace App\Http\Controllers;

class AdminController extends Controller {
    public function index() {
        return response()->json(['message' => 'Welcome, Admin']);
    }
}

Explanation:

  1. Implements Role-Based Access Control (RBAC), restricting users to certain endpoints based on roles.

  2. The middleware checks if the user's role matches the required role before accessing routes.

  3. The /admin endpoint is only accessible to admins, while /user is for normal users.

  4. Unauthorized access returns a 403 Forbidden response, enhancing API security.

  5. Useful for multi-user applications like e-commerce or SaaS platforms requiring permission management.


Example 2: API Rate Limiting

Limits requests per minute to prevent abuse.

File: routes/web.php

$router->get('/rate-limited', ['middleware' => 'throttle:5,1', 'uses' => 'RateLimitController@index']);

File: app/Http/Controllers/RateLimitController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

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

Explanation:

  1. Uses Lumen's built-in throttle middleware to limit requests per minute.

  2. The throttle:5,1 setting allows only 5 requests per minute per user.

  3. When the limit is exceeded, it returns a 429 Too Many Requests error.

  4. Helps prevent API abuse by bots and excessive traffic.

  5. Essential for public APIs, authentication endpoints, and payment gateways to maintain fair usage.


Example 3: WebSocket-based Real-Time Chat API

Enables real-time chat messages between users using WebSockets.

File: routes/web.php

$router->post('/message', 'ChatController@sendMessage');
$router->get('/messages', 'ChatController@getMessages');

File: app/Http/Controllers/ChatController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Message;
use App\Events\NewMessage;

class ChatController extends Controller {
    public function sendMessage(Request $request) {
        $message = Message::create([
            'user_id' => $request->user_id,
            'content' => $request->content
        ]);
        event(new NewMessage($message));
        return response()->json($message, 201);
    }

    public function getMessages() {
        return response()->json(Message::all());
    }
}

File: app/Events/NewMessage.php

<?php

namespace App\Events;

use App\Models\Message;
use Illuminate\Queue\SerializesModels;

class NewMessage {
    use SerializesModels;
    public $message;

    public function __construct(Message $message) {
        $this->message = $message;
    }
}

Explanation:

  1. Implements a real-time chat system using WebSockets and event broadcasting.

  2. Users can send and receive messages instantly.

  3. The NewMessage event triggers when a message is sent, updating all connected clients.

  4. Stores chat messages in a database for future retrieval.

  5. Suitable for messaging apps, support chats, and real-time dashboards.


Example 4: Task Queue with Jobs (Delayed Processing)

Processes long-running tasks asynchronously (e.g., sending reports, generating invoices).

File: routes/web.php

$router->post('/generate-report', 'ReportController@generateReport');

File: app/Http/Controllers/ReportController.php

<?php

namespace App\Http\Controllers;

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

class ReportController extends Controller {
    public function generateReport(Request $request) {
        dispatch(new GenerateReportJob($request->user_id));
        return response()->json(['message' => 'Report generation started'], 202);
    }
}

File: app/Jobs/GenerateReportJob.php

<?php

namespace App\Jobs;

use App\Models\User;
use Illuminate\Support\Facades\Mail;

class GenerateReportJob extends Job {
    protected $user_id;

    public function __construct($user_id) {
        $this->user_id = $user_id;
    }

    public function handle() {
        $user = User::find($this->user_id);
        Mail::raw("Your report is ready!", function ($message) use ($user) {
            $message->to($user->email)->subject("Report Completed");
        });
    }
}

Explanation:

  1. Uses job queues to process long-running tasks in the background.

  2. The job dispatches a report generation without blocking the request.

  3. A queued job sends an email notification when the report is ready.

  4. This improves performance and user experience for time-consuming operations.

  5. Ideal for batch processing, sending bulk emails, and generating invoices.


Example 5: Multi-Tenant SaaS API (Subdomain-based access)

Allows different organizations to have their own separate data.

File: routes/web.php

$router->group(['middleware' => 'tenant'], function () use ($router) {
    $router->get('/data', 'TenantController@getData');
});

File: app/Http/Middleware/TenantMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Models\Tenant;

class TenantMiddleware {
    public function handle(Request $request, Closure $next) {
        $subdomain = explode('.', $request->getHost())[0];
        $tenant = Tenant::where('subdomain', $subdomain)->first();

        if (!$tenant) {
            return response()->json(['error' => 'Tenant not found'], 404);
        }

        app()->instance('tenant', $tenant);
        return $next($request);
    }
}

Explanation:

  1. Supports multi-tenancy by assigning a unique subdomain to each organization.

  2. The middleware extracts the subdomain, verifying it against the database.

  3. If the tenant exists, it allows access to tenant-specific data.

  4. Prevents data mixing between organizations, maintaining security.

  5. Suitable for SaaS platforms where multiple customers need isolated environments.


Summary:

These examples cover RBAC, rate-limiting, real-time WebSockets, background jobs, and multi-tenancy, demonstrating advanced backend concepts for scalable Lumen applications.