UUID tipados y fallos de migración en Laravel 13.42
Laravel 13.42 mejora la entrada tipada, las migraciones fallidas y las automatizaciones con procesos y scheduler.
Evitar strings sin contexto en la entrada de una API
En muchas APIs recibimos UUID y ULID como texto, los validamos a medias y acabamos pasando cadenas por servicios, acciones y consultas. Laravel 13.42 incorpora uuid() y ulid() en la petición para recuperar esos valores como objetos tipados. No cambia el contrato HTTP, pero sí evita que la conversión quede repartida por capas donde no debería estar. (laravel.com)
Validar primero y convertir después
Yo usaría estos métodos justo después de validar la petición, no como sustitutos de la validación. uuid() devuelve una instancia de Ramsey\Uuid\UuidInterface y ulid() una de Symfony\Component\Uid\Ulid; si falta el dato, el resultado es null. Si el campo existe pero no tiene un formato válido, Laravel lanza una InvalidArgumentException. (laravel.com)
use Illuminate\Http\Request;
public function show(Request $request)
{
$request->validate([
'order_id' => ['required', 'uuid'],
'event_id' => ['nullable', 'ulid'],
]);
$orderId = $request->uuid('order_id');
$eventId = $request->ulid('event_id');
return response()->json([
'order_id' => (string) $orderId,
'event_id' => $eventId ? (string) $eventId : null,
]);
}La diferencia parece menor hasta que la aplicación tiene varios puntos de entrada: controladores, comandos, jobs o integraciones. Tener el identificador en un tipo conocido hace más explícito qué espera cada servicio y reduce conversiones manuales. También deja claro el lugar donde una entrada externa pasa a ser un dato válido de la aplicación.
Macros que siguen la cadena del proceso
Las automatizaciones que lanzan comandos desde Laravel suelen repetir ajustes: directorio de trabajo, variables de entorno, tiempo máximo o TTY. En esta versión, PendingProcess admite macros, así que esos ajustes se pueden encapsular aunque ya hayas llamado a métodos como tty() o path(). Es útil para homelabs, despliegues propios y tareas internas que ejecutan Composer, scripts de mantenimiento o herramientas de infraestructura. (github.com)
use Illuminate\Process\PendingProcess;
use Illuminate\Support\Facades\Process;
PendingProcess::macro('inProject', function (string $path) {
return $this
->path($path)
->timeout(120);
});
$result = Process::tty()
->inProject(base_path())
->run(['composer', 'install', '--no-interaction']);No es una razón para convertir PHP en un orquestador de shell sin límites. Conviene seguir usando listas de argumentos cuando sea posible, fijar tiempos de espera y no interpolar valores controlados por usuarios en comandos. La macro reduce repetición, pero no elimina los riesgos operativos ni las reglas de seguridad de proc_open.
Reaccionar cuando una migración deja el esquema a medias
El evento MigrationFailed da un punto central para reaccionar cuando una migración lanza una excepción. Esto es especialmente relevante si gestionas MySQL por tu cuenta y una operación de esquema ya ha cambiado parte de la base de datos antes de que falle un paso posterior. El evento no oculta el error: Laravel lo dispara y la excepción continúa su recorrido normal. (github.com)
use Illuminate\Database\Events\MigrationFailed;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
Event::listen(function (MigrationFailed $event): void {
Log::critical('Migration failed', [
'migration' => $event->name,
'exception' => $event->exception->getMessage(),
]);
});Para mí, el valor está en conectar esta señal con la operación real: una alerta, una marca de incidencia o una acción que evite que trabajadores y usuarios usen un esquema incoherente. No hace falta automatizar una respuesta destructiva en el primer día. Primero registraría el contexto suficiente, probaría el flujo en staging y decidiría qué medida tiene sentido para cada aplicación.
Saber por qué el scheduler no ejecutó una tarea
El scheduler ya permitía condicionar tareas con métodos como when(), skip(), withoutOverlapping() y onOneServer(). Laravel 13.42 añade una razón al evento ScheduledTaskSkipped, algo práctico cuando una automatización aparentemente no ha hecho nada. Registrar ese motivo ayuda a distinguir una condición de negocio de un scheduler pausado o de una ejecución reservada por otro servidor. (github.com)
use Illuminate\Console\Events\ScheduledTaskSkipped;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
Event::listen(function (ScheduledTaskSkipped $event): void {
Log::info('Scheduled task skipped', [
'task' => $event->task->getSummaryForDisplay(),
'reason' => $event->reason?->value,
]);
});Esto encaja bien con automatizaciones que dependen de bloqueos compartidos, como las que usan onOneServer() o withoutOverlapping(). En una instalación pequeña puede bastar con dejar el evento en logs; en una infraestructura con varios nodos, ese mismo dato es útil para telemetría. Lo importante es no confundir una tarea omitida con una tarea ejecutada correctamente.
La letra pequeña
uuid() y ulid() no validan por ti ni convierten un identificador inválido en una respuesta HTTP adecuada. Si llamas al método antes de validar, tendrás que decidir cómo tratar la excepción; para una API pública, normalmente interesa que la validación produzca una respuesta 422 consistente. Tampoco resuelven el diseño de las claves de tu base de datos ni sustituyen el tipado de tus propios DTO.
MigrationFailed no revierte cambios de esquema ni repara una migración parcialmente aplicada. Es una señal para reaccionar, no un mecanismo de recuperación automática, y una acción como poner la aplicación en mantenimiento debe probarse con cuidado. Las macros de PendingProcess tampoco aíslan procesos ni sustituyen colas, supervisión o límites de recursos cuando una automatización puede durar demasiado.
Una mejora pequeña con efectos prácticos
No veo aquí una función para reescribir una aplicación, y eso es precisamente lo interesante. La entrada tipada reduce ambigüedad en APIs, las macros limpian automatizaciones repetidas y los eventos mejoran la observabilidad donde más duele: migraciones y tareas programadas. Son cambios que aprovecharía de forma gradual, empezando por los endpoints y procesos donde hoy hay más conversión manual y menos contexto operativo.
Fuente: Laravel News. (laravel-news.com) Documentación oficial: HTTP Requests, Processes y Task Scheduling. (laravel.com) Código oficial: MigrationFailed, macros en PendingProcess y razones en ScheduledTaskSkipped. (github.com)