<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
if (!$request->user()) {
abort(401, 'Unauthenticated');
}
if (!$request->user()->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions');
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class LogApiRequests
{
public function handle(Request $request, Closure $next): Response
{
$startTime = microtime(true);
// Modify request if needed
$request->headers->set('X-Request-ID', $requestId = str()->uuid());
$response = $next($request);
// Log after response is generated
$duration = round((microtime(true) - $startTime) * 1000, 2);
Log::info('API Request', [
'request_id' => $requestId,
'method' => $request->method(),
'path' => $request->path(),
'status' => $response->getStatusCode(),
'duration_ms' => $duration,
'user_id' => $request->user()?->id,
]);
return $response;
}
public function terminate(Request $request, Response $response): void
{
// Runs after response sent to browser
// Good for heavy operations like analytics
}
}
<?php
use Illuminate\Support\Facades\Route;
Route::middleware(['auth:sanctum', 'role:admin,editor'])
->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
});
Route::middleware(['auth:sanctum', 'role:admin'])
->prefix('admin')
->group(function () {
Route::get('/users', [UserController::class, 'index']);
Route::delete('/users/{user}', [UserController::class, 'destroy']);
});
Middleware intercepts HTTP requests before they reach controllers, perfect for authentication, logging, or request modification. I create middleware classes with a handle() method that receives the request and a $next closure. Middleware can inspect/modify requests before passing them forward or inspect/modify responses after. Global middleware runs on every request, while route middleware applies selectively. Middleware groups like web and api apply common middleware stacks. The terminate() method runs after the response is sent to the browser, useful for logging or cleanup. Middleware parameters enable reusable logic—a role middleware that accepts role names. The middleware pipeline is Laravel's request/response filter chain.
Related snips
export interface RetryOptions {
retries: number;
baseMs: number;
maxMs: number;
signal?: AbortSignal;
onRetry?: (attempt: number, delay: number, err: unknown) => void;
Exponential backoff with jitter for retries
<?php
namespace App\Providers;
use App\Contracts\PaymentGateway;
use App\Services\StripePaymentGateway;
Laravel service container and dependency injection
package deps
import (
"net"
"net/http"
"time"
HTTP client tuned for production: timeouts, transport, and connection reuse
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
Laravel mix/Vite for asset compilation
package api
import (
"io"
"net/http"
"os"
Safe multipart uploads using temp files (bounded memory)
package deps
import (
"crypto/tls"
"crypto/x509"
"net/http"
mTLS client configuration with custom root CA pool
Share this code
Here's the card — post it anywhere.