Middleware Pattern

What Is It?

Middleware provides a mechanism to filter and process HTTP requests and responses. Each middleware performs a specific task and passes the request to the next middleware in the chain.

Why?

Cross-cutting concerns (authentication, logging, CORS, rate limiting) apply to many routes. Without middleware, these checks must be duplicated in every controller.

When to Use

For any cross-cutting HTTP concern: authentication, authorization, rate limiting, CORS, logging, input sanitization, response modification.

When Not to Use

For business logic that should be in controllers or services. For one-off checks that only apply to a single endpoint.

Example

Example
<?php
// Custom middleware
class EnsureUserIsActive
{
    public function handle(Request $request, Closure $next): Response
    {
        if (auth()->check() && ! auth()->user()->is_active) {
            auth()->logout();
            return redirect()->route('login')
                ->withErrors(['email' => 'Your account has been deactivated.']);
        }
        
        return $next($request);
    }
}

// Middleware with parameters
class EnsureRole
{
    public function handle(Request $request, Closure $next, string ...$roles): Response
    {
        if (! auth()->check() || ! in_array(auth()->user()->role->slug, $roles)) {
            abort(403, 'Unauthorized');
        }
        return $next($request);
    }
}

// Usage in routes
Route::middleware(['auth', 'EnsureUserIsActive'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
});

Route::middleware('role:admin,super-admin')->group(function () {
    Route::resource('users', UserController::class);
});

// Middleware order matters
Route::middleware(['web', 'auth', 'verified'])->group(...);

Pros

  • DRY principle for cross-cutting concerns
  • Composable and reusable
  • Clean separation of HTTP concerns
  • Easy to test
  • Laravel has built-in middleware support

Cons

  • Order matters and can cause bugs
  • Hard to debug middleware stack
  • Can add processing overhead
  • Too many middleware layers reduce readability