Language:

Search

Tip Laravel: usa Route::pattern() para que no tengas que reordenar rutas

  • Share this:
Tip Laravel: usa Route::pattern() para que no tengas que reordenar rutas

Hay un detalle clásico en Laravel que tarde o temprano te muerde: dos rutas que compiten porque una tiene un parámetro “genérico” ({id}) y otra espera un string (slug, acción, “me”, “latest”, etc.).
Y cuando pasa… acabas moviendo rutas arriba y abajo en api.php o web.php como si fuera Tetris. 😅

La buena noticia: puedes evitarlo con Route::pattern().


El problema típico

Imagina que tienes esto:

Route::get('/user/supply/{id}', [SupplyController::class, 'mySupply']);


Y luego agregas otra ruta, donde lo que viene después de /supply/ es un string:

Route::get('/user/supply/latest', [SupplyController::class, 'latestSupply']);


Si /user/supply/{id} está antes, Laravel puede interpretar "latest" como {id} y entonces:

o entra en mySupply("latest")

o te revienta más tarde porque esperabas un número

Solución rápida que todos hacemos: subir la ruta “latest” arriba.
Pero eso escala fatal cuando el archivo crece.


La solución elegante: restringe el patrón del parámetro

Si tú sabes que {id} siempre va a ser numérico, díselo a Laravel una vez y te olvidas.

En tu AppServiceProvider:

use Illuminate\Support\Facades\Route;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
    }

    public function boot(): void
    {
        Route::pattern('id', '[0-9]+');
    }
}


Con eso, cualquier parámetro llamado id en tus rutas solo va a matchear números.


Cómo queda tu ejemplo (sin reordenar nada)

Route::get('/user/supply/{id}', [SupplyController::class, 'mySupply']);
Route::get('/user/supply/latest', [SupplyController::class, 'latestSupply']);

Ahora pasa esto:

GET /user/supply/123mySupply(123)

GET /user/supply/latestlatestSupply()

GET /user/supply/abc → 404 (y eso está perfecto)

Porque {id} ya no se “come” strings.


Detalle importante

Esto aplica solo si usas el mismo nombre del parámetro.

O sea, si defines:

Route::pattern('id', '[0-9]+');


Entonces funciona para {id}, pero no para {userId} o {supply_id} (a menos que también les definas patrón).


En resumen


Si tus {id} son numéricos, decláralo globalmente con Route::pattern() y olvídate de estar ordenando rutas a mano cada vez que agregas una nueva.

Una vez lo metes en el proyecto, es de esas cosas que dices: “¿cómo no hice esto antes?”

Carlos Santiago

Carlos Santiago

Laravel Developer