Saltar al contenido

Laravel Context, introducido en Laravel 11, permite compartir datos a través de toda tu aplicación durante una request o job, sin pasar parámetros manualmente entre capas. Todo lo que almacenes estará disponible en controladores, servicios, eventos, jobs y automáticamente en los logs.

Por qué usar Context

Sin Context, compartir información contextual es tedioso:

// Sin Context: parámetros por todas partes
class OrderService
{
    public function create(array $data, string $requestId, int $userId): Order
    {
        $order = Order::create($data);
        $this->notificationService->send($order, $requestId, $userId);
        $this->auditService->log($order, $requestId, $userId);
        
        return $order;
    }
}

Con Context:

// Con Context: métodos limpios
class OrderService
{
    public function create(array $data): Order
    {
        $order = Order::create($data);
        $this->notificationService->send($order);
        $this->auditService->log($order);
        
        return $order;
    }
}

// En cualquier parte
$requestId = Context::get('request_id');
$userId = Context::get('user_id');

Uso básico

use Illuminate\Support\Facades\Context;

// Almacenar
Context::add('request_id', Str::uuid()->toString());
Context::add(['user_id' => 1, 'tenant_id' => 5]);

// Recuperar
$requestId = Context::get('request_id');
$locale = Context::get('locale', 'es'); // Con default

// Verificar y eliminar
Context::has('user_id');
Context::forget('temporary_data');
$value = Context::pull('one_time_token'); // Obtiene y elimina

// Añadir solo si no existe
Context::addIf('request_id', Str::uuid()->toString());

Inicialización con Middleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Context;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class InitializeContext
{
    public function handle(Request $request, Closure $next): Response
    {
        Context::add([
            'request_id' => Str::uuid()->toString(),
            'ip' => $request->ip(),
            'url' => $request->fullUrl(),
        ]);

        if ($user = $request->user()) {
            Context::add('user_id', $user->id);
        }

        return $next($request);
    }
}

Integración con Logs

Todo el contexto se añade automáticamente a cada log:

Context::add('request_id', 'abc-123');
Context::add('user_id', 42);

Log::info('Pedido procesado');
// [2024-01-15 10:30:00] local.INFO: Pedido procesado {"request_id":"abc-123","user_id":42}

Para excluir datos sensibles de los logs:

Context::addHidden('api_token', $token); // No aparece en logs
$token = Context::getHidden('api_token'); // Pero sigue accesible

Context en Jobs

El contexto se serializa y restaura automáticamente en jobs:

// En el controlador
Context::add('request_id', Str::uuid()->toString());
Context::add('user_id', auth()->id());

ProcessOrder::dispatch($order);
// En el job
public function handle(): void
{
    // El contexto original está disponible
    $requestId = Context::get('request_id');
    
    Log::info("Procesando pedido {$this->order->id}");
    // Log incluirá request_id y user_id automáticamente
}

Stacks: Acumular valores

Context::push('breadcrumbs', 'Usuario visitó dashboard');
Context::push('breadcrumbs', 'Usuario creó pedido');

$breadcrumbs = Context::get('breadcrumbs');
// ['Usuario visitó dashboard', 'Usuario creó pedido']

Casos de uso prácticos

Trazabilidad entre servicios

// Propagar trace_id a otros servicios
Http::withHeaders([
    'X-Trace-ID' => Context::get('trace_id'),
])->post('https://api.otro-servicio.com/endpoint');

Multi-tenancy

Context::add('tenant_id', $tenant->id);

// Disponible en toda la aplicación y en todos los logs
Log::warning('Límite alcanzado');
// {"tenant_id": 5, ...}

Auditoría automática

trait Auditable
{
    public static function bootAuditable(): void
    {
        static::created(function ($model) {
            AuditLog::create([
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'action' => 'created',
                'user_id' => Context::get('user_id'),
                'request_id' => Context::get('request_id'),
                'ip' => Context::get('ip'),
            ]);
        });
    }
}

Buenas prácticas

Usa constantes para las claves:

final class ContextKeys
{
    public const REQUEST_ID = 'request_id';
    public const USER_ID = 'user_id';
    public const TENANT_ID = 'tenant_id';
}

No abuses: Context es para datos transversales (logging, auditoría), no para pasar datos entre dos métodos específicos.

Evita datos grandes: Se serializa con cada job y se incluye en cada log.

Conclusión

Laravel Context simplifica la gestión de datos contextuales con integración nativa en logs y jobs. Ideal para trazabilidad, multi-tenancy y auditoría sin contaminar las firmas de tus métodos.

school Curso completo

Curso Laravel 12
Completo 2026

El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.

access_time 8 horas de contenido
layers 4 tecnologías en 1
update 100% actualizado
code Proyectos prácticos
Ver Curso Laravel 12 arrow_forward

star Incluido en cualquier suscripción

Rutas de aprendizaje