Dominando el middleware Terminable de Laravel: la magia posterior a la respuesta

  • Publicado el 20 noviembre, 2024
  • Palabras: 276

En el mundo del desarrollo web, el tiempo lo es todo. A veces, es necesario realizar acciones después de que se haya enviado la respuesta al navegador. Aquí es donde entra en juego el middleware Terminable de Laravel, una función potente que permite ejecutar código después de que se haya enviado la respuesta HTTP. Veamos cómo se puede aprovechar esta función para optimizar las aplicaciones de Laravel.

Dominando el middleware Terminable de Laravel: la magia posterior a la respuesta

#Entendiendo el middleware Terminable

El middleware Terminable en Laravel permite definir un método de terminación que se llama después de que se haya enviado la respuesta al navegador. Esto es particularmente útil para tareas que no necesitan retrasar la respuesta al cliente, como ciertos tipos de registro, operaciones de limpieza o ejecución de trabajos en cola.

 

#Crear el middleware Terminable

A continuación se explica cómo crear un middleware Terminable:

 

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateHttpRequest;
use SymfonyComponentHttpFoundationResponse;

class TerminatingMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);
    }

    public function terminate(Request $request, Response $response): void
    {
        // Post-response logic here
    }
}

 

El método terminate() recibe tanto la solicitud como la respuesta, lo que le permite realizar acciones en función del estado final de ambas.

 

#Registrar el middleware Terminable

Para utilizar middleware Terminable, agréguelo a su pila de middleware global o enrute el middleware en bootstrap/app.php:

 

->withMiddleware(function (Middleware $middleware) {
    $middleware->append([
        AppHttpMiddlewareTerminatingMiddleware::class,
    ]);
})

 

#Garantizar un estado coherente

De forma predeterminada, Laravel resuelve una nueva instancia del middleware para el método de terminación. Si necesita mantener el estado entre el identificador y la terminación, registre el middleware como un singleton en su AppServiceProvider:

 

use AppHttpMiddlewareTerminatingMiddleware;

public function register(): void
{
    $this->app->singleton(TerminatingMiddleware::class);
}

 

#Ejemplo práctico

Consideremos un escenario en el que queremos registrar el uso de la API sin ralentizar nuestras respuestas. Crearemos un middleware terminable que registre los detalles de la solicitud y el tiempo de respuesta después de que se haya enviado la respuesta:

 

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateHttpRequest;
use IlluminateSupportFacadesLog;
use SymfonyComponentHttpFoundationResponse;

class ApiUsageLogger
{
    protected $startTime;

    public function handle(Request $request, Closure $next): Response
    {
        $this->startTime = microtime(true);
        return $next($request);
    }

    public function terminate(Request $request, Response $response): void
    {
        $duration = microtime(true) - $this->startTime;
        
        Log::info('API Call', [
            'url' => $request->fullUrl(),
            'method' => $request->method(),
            'status' => $response->getStatusCode(),
            'duration' => round($duration * 1000, 2) . 'ms',
            'ip' => $request->ip(),
        ]);
    }
}

 

Ahora, apliquemos este middleware a nuestras rutas API:

 

Route::middleware(['api', ApiUsageLogger::class])->group(function () {
    Route::get('/users', [UserController::class, 'index']);
    // Other API routes...
});

 

Con esta configuración, cada llamada a la API se registrará después de que se haya enviado la respuesta, sin afectar el tiempo de respuesta. Así es como podría verse la entrada del registro:

 

{
    "message": "API Call",
    "context": {
        "url": "https://api.example.com/users",
        "method": "GET",
        "status": 200,
        "duration": "45.67ms",
        "ip": "192.168.1.1"
    }
}

 

Si dominas el middleware Terminable, podrás optimizar sus aplicaciones Laravel, mejorando el rendimiento y la capacidad de mantenimiento. Ya sea que esté registrando, limpiando recursos o activando procesos en segundo plano, el middleware Terminable proporciona una forma limpia y eficiente de manejar operaciones posteriores a la respuesta.

Antonio Jenaro

Desarrollador backend especializado en PHP y Laravel, con sede en Santander, Cantabria. Más de 15 años de experiencia en el desarrollo de aplicaciones web a medida y en la modernización de código heredado.

Archivado en:

Fuente: Harris Raftopoulos

Inicia la conversación

Hazte miembro de Antonio Jenaro para comenzar a comentar.

Regístrate ahora

¿Ya estás registrado? Inicia sesión