Advanced

Middleware

The middleware pipeline — applying middleware, ordering, the built-in alias catalog, and the PSR-15 bridge.

The reference for Glueful's middleware pipeline: how to apply middleware, ordering, the built-in alias catalog, and PSR-15.

What is Middleware?

Middleware sits between the request and your controller, allowing you to:

  • Authenticate requests
  • Log requests/responses
  • Transform data
  • Add headers
  • Rate limit
  • Cache responses

Applying Middleware

Route-Level

// Single middleware
$router->get('/profile', [ProfileController::class, 'show'])
    ->middleware('auth');

// Multiple middleware
$router->post('/posts', [PostController::class, 'store'])
    ->middleware(['auth', 'csrf']);

Group Middleware

$router->group(['middleware' => ['auth']], function($router) {
    $router->get('/dashboard', [DashboardController::class, 'index']);
    $router->get('/profile', [ProfileController::class, 'show']);
    $router->post('/posts', [PostController::class, 'store']);
});

Global Middleware

Apply to all routes:

$router->group(['middleware' => ['security_headers', 'request_logging']], function($router) {
    require __DIR__ . '/../routes/api.php';
});

Middleware Ordering

Order matters! Middleware executes in the order defined:

// ✅ Good order
$router->group(['middleware' => [
    'cors',              // Handle CORS first
    'rate_limit',        // Rate limit early
    'auth',              // Then authenticate
    'role:admin',        // Check permissions
    'request_logging',   // Log after checks
]], function($router) {
    // Routes
});

// ❌ Bad order
$router->group(['middleware' => [
    'request_logging',   // Logs unauthorized requests
    'role:admin',        // Checks role before auth
    'auth',              // Authenticates too late
    'rate_limit',        // Rate limits after expensive work
]], function($router) {
    // Routes
});

Built-in Middleware Aliases

The framework registers these string aliases (in CoreProvider); use them by name in a route's ->middleware([...]) or a group's middleware:

AliasMiddlewareWhat it does
authAuthMiddlewareAuthenticates the request (JWT / session / API key) and populates the user context; returns 401 if unauthenticated.
rate_limitEnhancedRateLimiterMiddlewareEnforces rate limits. Attach the alias, but set the actual limits with the ->rateLimit($max, $minutes) builder — the limiter reads the route's rate-limit config, not rate_limit:max,window string params.
require_scopeRequireScopeMiddlewareEnforces #[RequireScope('write:posts')] — gates the route by API-key scope. The attribute auto-attaches this middleware.
gate_permissionsGateAttributeMiddlewareEnforces #[RequiresPermission] / #[RequiresRole] on the handler through the authorization Gate (RBAC providers such as glueful/aegis back it).
auth_to_requestAuthToRequestAttributesMiddlewareCopies the authenticated identity + claims into request attributes so downstream permission checks can read them.
adminAdminPermissionMiddlewareRequires an admin-level permission.
validateValidationMiddlewareRuns #[Validate] attribute validation before the handler.
field_selectionFieldSelectionMiddlewareApplies GraphQL-style field selection / expansion (?fields=, ?expand=).
csrfCSRFMiddlewareCSRF token protection for state-changing requests.
security_headersSecurityHeadersMiddlewareAdds security response headers.
allow_ipAllowIpMiddlewareRestricts the route to an IP allowlist.
lockdownLockdownMiddlewareEmergency / maintenance lockdown.
conditional_cacheConditionalCacheMiddlewareConditional (ETag / 304 Not Modified) response caching.
metricsMetricsMiddlewareRecords API metrics for the request.
tracingTracingMiddlewareEmits request tracing / observability spans.
request_loggingRequestResponseLoggingMiddlewareLogs the request and response.

The classes live under Glueful\Routing\Middleware\*, except gate_permissions/auth_to_request (Glueful\Permissions\Middleware\*), validate (Glueful\Validation\Middleware\*), and rate_limit (Glueful\Api\RateLimiting\Middleware\*). Aliases are registered in CoreProvider; enabled extensions can register their own. In a middleware([...]) array you can mix bare names, name:param strings (for middleware that read runtime params), and class instances.

PSR-15 Middleware

Glueful includes a built‑in PSR‑15 bridge. You can attach any PSR‑15 middleware directly, and the router will auto‑wrap it when http.psr15.enabled and http.psr15.auto_detect are true (default).

use Middlewares\Cors; // example third‑party PSR‑15 middleware

$psrMiddleware = new Cors();

$router->get('/data', [ApiController::class, 'index'])
    ->middleware([$psrMiddleware]); // router detects and wraps PSR‑15

Configuration (config/http.php):

'psr15' => [
    'enabled' => env('PSR15_ENABLED', true),
    'auto_detect' => env('PSR15_AUTO_DETECT', true),
    // Optional factory provider for PSR‑17 factories; auto‑detected if omitted
    'factory_provider' => null,
    'throw_on_missing_bridge' => env('PSR15_STRICT', true),
],

How it works (for reference):

  • Router auto-detects PSR‑15 middleware and wraps it via a resolver trait: src/Routing/Internal/Psr15MiddlewareResolverTrait.php
  • The bridge that exposes Glueful middleware as PSR‑15 and performs conversions lives at: src/Http/Bridge/Psr15/MiddlewareAsPsr15.php
  • Toggle behavior and factory provisioning in: config/http.php

Next Steps