Architecture Overview Building a multi-sided marketplace requires more than just database tables; it demands a clear separation of concerns. This structure involves three distinct user areas—**Consumer**, **Homeowner**, and **Service Provider**—alongside a dedicated administrative backend. By isolating these spaces, you maintain granular control over branding for public-facing users while utilizing rapid-development tools for internal management. Prerequisites To implement this architecture, you should have a firm grasp of PHP 8.1+ and the Laravel framework. Familiarity with Blade templating, Middleware, and PHP Enums is essential for managing the role-based logic effectively. Key Libraries & Tools - **Filament**: An admin panel builder used here for internal system tools and CRUD operations. - **Laravel Daily Starter Kit**: A minimalist Blade-based foundation for the public UI. - **Mermaid.js**: Used for visualizing the flow of user roles and access points. Code Walkthrough: Role Management The foundation of this system is a strict PHP Enum that defines the possible user roles. This prevents string-matching errors and provides a central source of truth. ```php enum UserRole: string { case CONSUMER = 'consumer'; case HOME_OWNER = 'home_owner'; case SERVICE_PROVIDER = 'service_provider'; case ADMIN = 'admin'; } ``` Custom Role Middleware To protect routes, a custom middleware checks if the authenticated user's role matches the required permission. This is registered in `bootstrap/app.php` using the alias `role`. ```php public function handle(Request $request, Closure $next, ...$roles) { if (!in_array($request->user()->role->value, $roles)) { abort(403); } return $next($request); } ``` Namespace Separation Each role has its own directory in `app/Http/Controllers` and `resources/views`. This prevents massive, cluttered folders and makes the project infinitely more searchable. ```php Route::middleware(['auth', 'role:consumer'])->prefix('app/consumer')->name('consumer.')->group(function () { Route::get('dashboard', [Consumer\DashboardController::class, 'index'])->name('dashboard'); }); ``` Syntax Notes Notice the use of **variadic parameters** (`...$roles`) in the middleware. This allows you to pass a comma-separated list of roles to a single route group, accommodating users who hold multiple roles simultaneously. Practical Examples In a real estate context, a **Homeowner** may need to search for other properties. By allowing multiple roles in the middleware, the homeowner can access `consumer` routes without duplicating controllers or logic. This "overlapping role" strategy is common in marketplaces like Booking.com. Tips & Gotchas - **Strict Enums**: Avoid using a simple `roles` table if your application logic (routes, controllers, views) is tied specifically to those roles. Adding a new role requires new code, not just a database row. - **Automated Testing**: Always write feature tests to ensure a `service_provider` cannot access `/admin` or `/consumer` endpoints. This is your final safety net against permission leaks.
Blade
Software
- Nov 28, 2025
- Aug 5, 2024
- Dec 21, 2023
- Oct 13, 2021
- Feb 11, 2021
The Architecture of Choice in Laravel 8 Laravel 8 marks a significant shift in how we approach the front-end, or more accurately, how we don't. By default, the framework remains entirely agnostic. When you run `laravel new`, you get Blade templates and nothing else. No Tailwind, no Vue, and certainly no forced architectural patterns. This is intentional. The goal is to provide a clean slate while offering powerful, optional scaffolding for those who want to move faster. Much of the recent noise in the community suggests that using tools like Inertia.js or Livewire is a requirement or a "betting of the farm" on immature tech. This fundamentally misunderstands what these tools do. Inertia isn't a massive framework; it's a bridge that lets you use Laravel's routing to hydrate Vue components. It keeps you productive by removing the need for a separate API repository, which is often a productivity killer for solo developers and small teams. Demystifying the Starter Kits: Breeze and Jetstream To understand where you should start, you have to look at the complexity of your requirements. Laravel Breeze represents the baseline. It is a simple, minimal implementation of all Laravel's authentication features—login, registration, password reset—using simple controllers and routes that you can actually see and modify in your app. It’s the spiritual successor to the old `make:auth` command, but modernized with Tailwind. Laravel Jetstream sits at the other end of the spectrum. It is essentially the free, open-source core of what used to be Laravel Spark. We moved all the non-billing features—team management, two-factor authentication, and API token management—out of Spark and into Jetstream. It uses Laravel Fortify as its headless backend. This means Jetstream handles the UI (via either Inertia or Livewire), while Fortify handles the heavy lifting of authentication logic in the background. Passport vs. Sanctum: Choosing Your API Guard The most persistent confusion in our ecosystem revolves around Laravel Passport and Laravel Sanctum. The decision tree is actually quite simple: if you need to build a full OAuth2 server—the kind where users can "Sign in with Your App" on third-party sites—you need Passport. It is a robust, compliant implementation built on the league/oauth2-server. However, most developers don't actually need OAuth2. They just need to secure an API or a Single Page Application (SPA). For these use cases, Passport is a sledgehammer. Sanctum was built to solve the "API for myself" problem. It provides a lightweight way to issue personal access tokens and, more importantly, a way to authenticate SPAs using secure, stateful cookies. The Secret Sauce of SPA Authentication Sanctum's true power lies in its ability to toggle between token-based and cookie-based authentication. When your SPA sits on the same top-level domain as your Laravel API, you shouldn't be messing with JWT storage in `localStorage`. It’s insecure and unnecessary. Instead, Sanctum allows your SPA to call a login endpoint, which uses standard Laravel session guards to issue a secure HTTP-only cookie. The browser then handles that cookie automatically for every subsequent request. If a request comes in without a cookie, the Sanctum guard looks for a `Bearer` token in the header. This dual-layer approach allows the same API routes to serve your first-party SPA via cookies and third-party mobile apps or SDKs via tokens. It’s the most secure and streamlined way to handle modern web authentication without the overhead of a full OAuth2 handshake. Community Dynamics and Open Contributions There is a narrative that the Laravel ecosystem is a closed circle, but the data proves otherwise. With over 2,800 contributors, the "inner circle" is massive. Developers like Paris Malhotra prove that anyone can show up, submit high-quality pull requests to core packages like Laravel Horizon, and get them merged. This isn't about personal friendships; it's about labor and merit. People like Caleb Porzio and Jonathan Reinink earned their status through hundreds of hours of free work to make the ecosystem better. We want people who bring positive energy and a desire to make programming more enjoyable. If you're here to armchair quarterback, you're missing the point of what we're building.
Dec 31, 2020