Mastering Laravel Middleware: Pre and Post Request Processing

Mastering Laravel Middleware: Pre and Post Request Processing

When building web applications with Laravel, controlling the flow of HTTP requests is crucial. Laravel's middleware provides a powerful mechanism to filter and manipulate HTTP requests entering your application. In this post, we'll dive deep into how you can leverage middleware for both pre and post-request processing.

Understanding Laravel Middleware

Middleware acts as a convenient mechanism for filtering HTTP requests entering your application. Think of it as a series of layers that the request must pass through before it reaches your application's core.

Types of Middleware

Laravel allows you to create two types of middleware:

  • Before Middleware: Executes tasks before the request is handled by the application.
  • After Middleware: Performs operations after the application has processed the request.

Let's look at examples of both types:

Before Middleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class BeforeMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        // Perform action before the request is handled
        $request->headers->set('X-Track-Id', uniqid());
        
        return $next($request);
    }
}

In this example, the middleware adds a tracking ID to the request headers before passing it further down the application stack.

After Middleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AfterMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);
        
        // Perform action after the request is handled
        $response->headers->set('X-Track-Id', $request->header('X-Track-Id'));
        
        return $response;
    }
}

This middleware captures the response, adds the tracking ID from the request to the response headers, and then returns the response.

Real-Life Example

Let's consider a scenario where we want to track the processing time of each request in our application. We can use a combination of Before and After middleware to achieve this.

First, let's create a TrackRequestTime middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TrackRequestTime
{
    public function handle(Request $request, Closure $next): Response
    {
        $request->attributes->set('start_time', microtime(true));
        
        $response = $next($request);
        
        $duration = microtime(true) - $request->attributes->get('start_time');
        $response->headers->set('X-Request-Duration', round($duration * 1000, 2) . 'ms');
        
        return $response;
    }
}

Now, let's apply this middleware to a route:

Route::get('/api/users', function () {
    // Simulate some processing time
    sleep(1);
    return User::all();
})->middleware(TrackRequestTime::class);

When we make a request to this route, the middleware will:

  • Set a start time before the request is processed
  • Allow the request to be handled by the application
  • Calculate the duration after the response is generated
  • Add the duration to the response headers

The output will look something like this:

// Response headers
{
    "X-Request-Duration": "1002.45ms"
}

// Response body
[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    {
        "id": 2,
        "name": "Jane Doe",
        "email": "jane@example.com"
    }
]

If you found this guide helpful, don't forget to subscribe to my daily newsletter and follow me on X/Twitter for more Laravel tips and tricks!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe