Routing
Routing
Basic Routing
La forma más básica de routing es una URI y una closure
use Illuminate\Support\Facades\Route;
Route::get('/greeting', function () {
return 'Hello World';
});
The Default Routes files
Todas las rutas están definidas en el directorio routes. Estos ficheros son cargados por Laravel usando la configuración de bootstrap/app.php
El archivo routes/web.php define las rutas que son para tu interfaz web. Estas rutas se asignan al grupo de middleware web, que proporciona funciones como el estado de la sesión y la protección CSRF.
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
Api Routes
Si tu aplicación va a ofrecer una api sin estado, puedes habilitarlo usando:
php artisan install:api
Este comando te instala el paquete de Laravel Sanctum el cual provee autenticacion usando tokens, el cual puede usarse para la autenticacion de apis de terceros, SPAs, o aplicaciones de móvil. El comando te crea también el archivo routes/api.php
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Las rutas en routes/api.php son sin estado, En aplicaciones REST, cada solicitud debe contener toda la información necesaria para ser entendida por el servidor, en lugar de depender de que el servidor recuerde solicitudes anteriores. Por otra parte el como también añade el fichero routes/api.php
Las rutas en routes/api.php son sin estado y están asignadas al grupo de middleware api. Además, el prefijo URI /api se aplica automáticamente a estas rutas, por lo que no es necesario aplicarlo manualmente a cada ruta en el archivo. Puedes cambiar el prefijo modificando el archivo bootstrap/app.php de tu aplicación.
->withRouting(
api: __DIR__.'/../routes/api.php',
apiPrefix: 'api/admin',
// ...
)
Available Router Methods
El router permite registrar cualquier ruta con cualquier verbo Http:
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
En alguna ocasión se necesita responder a varios verbos, puedes realizar esto usando match o responder a cualquier verbo usando any
Route::match(['get', 'post'], '/', function () {
// ...
});
Route::any('/', function () {
// ...
});
⚠️ Cuando se define una uri que recibe un parámetro es recomendable ponerlo a lo último. En este ejemplo si ponemos antes la ruta que recibe el parámetro, cuando llamemos a la segunda se va a llamar a la primera ruta dado que entenderá que el parámetro {user} es igual a ‘block’
❌
users/{user}
user/block
✅
user/block
users/{user}
⚠️ Al definir múltiples rutas que comparten la misma URI, las rutas que usan los métodos get, post, put, patch, delete y options deben definirse antes de las rutas que usan los métodos any, match y redirect. Esto asegura que la solicitud entrante coincida con la ruta correcta.
Dependency injection
En la definición de las rutas, en la closure puedes sugerir tipos para que se inyecten automáticamente desde el contenedor. En el ejemplo se inyecta Illuminate\Http\Request
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
// ...
});
CSRF Protection
Todos los formularios que realicen peticiones POST, PUT, PATCH, o DELETE en un formulario deberán incluir la anotación @csrf (esto es para blade).
<form method="POST" action="/profile">
@csrf
...
</form>
Redirects Routes
Si deseas redireccionar a otra ruta, puedes utilizar el metodo**Route::redirect**
Route::redirect('/here', '/there');
Por defecto devuelve un status code de 302 pero lo puedes modificar.
Route::redirect('/here', '/there', 301);
Route::permanentRedirect('/here', '/there');
// permanentRedirect siempre devuelve un 301
🚫 Cuando realizas un redirect pasando parametros, tener en cuenta que destination y status no pueden ser usadas dado que están reservadas.
View Routes
Si la ruta devuelve una vista, puedes usar Route::view pudiendo indicar el URI como primer argumento, la vista como segundo, y como tercer argumento un array con los datos a pasar a la vista.
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
🚫 Cuando realizas esto pasando parametros, tener en cuenta que view, data, status, headers, no pueden ser usadas dado que están reservadas.
Listing your routes
Puedes ver todas las rutas creadas con los siguientes comandos.
php artisan route:list
php artisan r:l
//listar las rutas definidas
php artisan route:list -v
// muestra tambien los middlewares
php artisan route:list -vv
// muestra tambien los middlewares de forma expandida
php artisan r:l --except-vendor
// no muestra las rutas de los vendors
php artisan route:list --only-vendor
// muestra solo las rutas de los vendors
php artisan route:list --path=api
// solo muestra las rutas que empiezan por api
Routing Customization
Por defecto, las rutas de tu aplicación son cargadas por bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)->create();
Aveces necesitas creas crear un subconjunto de rutas en otro archivo, puedes realizar esto con la función then y definiendo las rutas en el closure.
use Illuminate\Support\Facades\Route;
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
},
)
O tomando totalmente el control del registro de rutas con la función using cuando se pasa este argumento, el framework no registrará rutas solamente las que están definidas por nosotros dentro de la función.
use Illuminate\Support\Facades\Route;
->withRouting(
commands: __DIR__.'/../routes/console.php',
using: function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
},
)
Route Parameters
Algunas veces se necesitan capturar parametros que estan presentes en la URI:
Route::get('/user/{id}', function (string $id) {
return 'User '.$id;
});
Se pueden crear tantos parámetros como se necesiten
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
// ...
});
Los parametros estan siempre entre corchetes {} y dentro solamente caracteres alfabéticos.
Dentro del controlador o de la closure se reciben como parámetros en el orden definidos, incluso se puede incluir dependencias a inyectar por el contenedor
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, string $id) {
return 'User '.$id;
});
Optional Parameters
En ocasiones necesitas definir un parámetro que no siempre está disponible en la URI, podemos agregarle una ? para indicar que es opcional. Hay que ponerle un valor por defecto.
Route::get('/user/{name?}', function (?string $name = null) {
return $name;
});
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});
Regular Expressions Constraints
Puedes limitar los valores pasados por parámetro usando where, indicando el nombre del parametro y la expresión regular a cumplir.
Route::get('/user/{name}', function (string $name) {
// ...
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function (string $id) {
// ...
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
Se dispone de helpers que ayudan con expresiones regulares ya definidas.
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{name}', function (string $name) {
// ...
})->whereAlphaNumeric('name');
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUuid('id');
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUlid('id');
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', ['movie', 'song', 'painting']);
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', CategoryEnum::cases());
Si la ruta no concuerda con la expresión regular, se devuelve un 404.
Global Constraints
Si necesitas que un parámetro sea limitado en cualquiera de las rutas, puedes usar el método pattern Deberás definir este método en el boot de App\Providers\AppServiceProvider
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}
Ahora en cualquier ruta definida que tenga ese parámetro se comprobará la expresión
Route::get('/user/{id}', function (string $id) {
// Only executed if {id} is numeric...
});
Encoded Forward Slashes
Laravel permite todos los caracteres excepto el / como parte de un parámetro, hay que indicarlo explícitamente con el where
Route::get('/search/{search}', function (string $search) {
return $search;
})->where('search', '.*');
Named Routes
Se puede asignar un nombre a las rutas, permitiendo la conveniente generación de URL o redireccionamiento a una ruta especifica.
Route::get('/user/profile', function () {
// ...
})->name('profile');
Se pueden incluso especificar nombres para métodos de controladores
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');
⚠️ Los nombres de las rutas deben ser únicos.
Generating URL to Named Routes
A la hora de redireccionar o generar urls se pueden usar los nombres de la ruta usando route o el helper redirect()
// Generating URLs...
$url = route('profile');
// Generating Redirects...
return redirect()->route('profile');
return to_route('profile');
Si se requiere generar la ruta con parametros
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1]);
Los siguientes parámetros que no son requeridos son pasados como query params
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yes
Inspecting The Current Route
Podemos recuperar el nombre de la ruta actual por ejemplo en un middleware.
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
return $next($request);
}
Route Groups
Permite agrupar rutas pudiendo asignarles los mismos middlewares.
Middleware
Para asignar middlewares a un grupo de rutas, usamos el método middleware. Los middleware son ejecutas en el orden del array.
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});
Controllers
Si un grupo de rutas utilizan el mismo controlador, puedes usar el método controller para definir el controlador para todas las rutas.
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
Subdomain Routing
Los grupos de rutas también pueden usarse para manejar el enrutamiento de subdominios. Los subdominios pueden asignarse a parámetros de ruta al igual que las URIs de ruta, lo que te permite capturar una porción del subdominio para su uso en tu ruta o controlador. El subdominio puede especificarse llamando al método domain antes de definir el grupo.
Route::domain('{account}.example.com')->group(function () {
Route::get('user/{id}', function (string $account, string $id) {
// ...
});
});
⚠️ Para asegurar que tus rutas de subdominio sean accesibles, debes registrar las rutas de subdominio antes de registrar las rutas del dominio raíz. Esto evitará que las rutas del dominio raíz sobrescriban las rutas de subdominio que tienen la misma ruta URI.
Route Prefixes
Permite añadir un prefijo a un grupo de rutas.
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
Route Name Prefixes
El método name puede usarse para anteponer a cada nombre de ruta en el grupo una cadena dada. Por ejemplo, es posible que desees anteponer a los nombres de todas las rutas en el grupo la cadena admin. La cadena dada se antepone al nombre de la ruta exactamente como se especifica, por lo que debemos asegurarnos de proporcionar el carácter . al final del prefijo.
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
Asigna el nombre admin.users a la ruta de dentro.
Route Model Binding
Cuando una ruta tiene como parámetro un ID, laravel es capaz de recuperar de la base de datos ese registro e inyectar el objeto dentro del controlador o closure.
Implicit Binding
Laravel resuelve automáticamente los modelos Eloquent definidos en rutas o acciones de controlador cuyos nombres de variables con indicación de tipo coinciden con el nombre del segmento de la ruta. Por ejemplo:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
});
Dado que la variable $user tiene una indicación de tipo como el modelo Eloquent App\Models\User y el nombre de la variable coincide con el segmento de la URI {user}, Laravel inyectará automáticamente la instancia del modelo que tenga un ID que coincida con el valor correspondiente de la URI de la solicitud. Si no se encuentra una instancia de modelo coincidente en la base de datos, se generará automáticamente una respuesta HTTP 404.
Por supuesto, la vinculación implícita también es posible cuando se usan métodos del controlador. Nuevamente, observa que el segmento de URI {user} coincide con la variable $user en el controlador, la cual contiene una indicación de tipo App\Models\User.
use App\Http\Controllers\UserController;
use App\Models\User;
// Route definition...
Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}
Soft Deleted Models
Normalmente el model binding no devuelve registros que hayan sido soft delete. Para que los incluya tambien podemos usar el metodo withTrashed()
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();
Customizing the Key
Si se necesita resolver un modelo por otra clave diferente que no sea el id, hay que definir el parámetro por el que se va a consultar
use App\Models\Post;
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});
Si necesitas que siempre se resuelva por ese atributo, hay que indicarlo en el modelo de la siguiente forma:
/**
* Get the route key for the model.
*/
public function getRouteKeyName(): string
{
return 'slug';
}
Custom Keys and Scoping
Cuando asocias implícitamente múltiples modelos de Eloquent en una sola definición de ruta, es posible que desees delimitar el segundo modelo de Eloquent de manera que deba ser un hijo del modelo de Eloquent anterior. Por ejemplo, considera esta definición de ruta que recupera una publicación de blog por su slug para un usuario específico:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
Cuando uses una vinculación implícita con clave personalizada como un parámetro de ruta anidado, Laravel delimitará automáticamente la consulta para recuperar el modelo anidado por su padre usando convenciones para adivinar el nombre de la relación en el padre. En este caso, se asumirá que el modelo User tiene una relación llamada posts (la forma plural del nombre del parámetro de la ruta) que puede usarse para recuperar el modelo Post.
Si lo deseas, puedes instruir a Laravel para que delimite las vinculaciones “hijas” incluso cuando no se proporcione una clave personalizada. Para hacerlo, puedes invocar el método scopeBindings al definir tu ruta:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();
De manera similar, puedes instruir explícitamente a Laravel para que no delimite las vinculaciones invocando el método withoutScopedBindings:
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
})->withoutScopedBindings();
Customizing Missing Model Behavior
Normalmente cuando un modelo no es capaz de resolverse, se devuelve un 404, de todas formas se puede modificar este comportamiento con el método missing, la funcion acepta una closure que sera invocada si un modelo no se encuentra**.**
use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
->name('locations.view')
->missing(function (Request $request) {
return Redirect::route('locations.index');
});
Implicit Enum Binding
PHP 8.1 introdujo el soporte para Enums. Para complementar esta característica, Laravel permite usar un Backed Enum en tu definición de ruta y Laravel solo invocará la ruta si ese segmento de ruta corresponde a un valor válido de Enum. De lo contrario, se devolverá automáticamente una respuesta HTTP 404. Por ejemplo, dada la siguiente Enum:
<?php
namespace App\Enums;
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}
Puedes definir una ruta que solo será invocada si {category} corresponde con algún valor del Backed Enum.
use App\Enums\Category;
use Illuminate\Support\Facades\Route;
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});
Explicit Binding
No es necesario que uses la resolución implícita de modelos basada en convenciones de Laravel para utilizar el enlace de modelos. También puedes definir explícitamente cómo los parámetros de ruta se corresponden con modelos. Para registrar un enlace explícito, utiliza el método model del enrutador para especificar la clase para un parámetro dado. Debes definir tus enlaces explícitos de modelos al principio del método boot de tu clase AppServiceProvider.
use App\Models\User;
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::model('user', User::class);
}
Luego define una ruta que tiene un parámetro {user}
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
// ...
});
Como hemos enlazado todos los parámetros {user} al modelo App\Models\User, una instancia de esa clase será inyectada en la ruta. Por lo tanto, por ejemplo, una solicitud a users/1 inyectará la instancia del usuario desde la base de datos que tenga el ID 1.
Si no se encuentra una instancia del modelo que coincida en la base de datos, automáticamente se generará una respuesta HTTP 404.
Customizing the Resolution Logic
Si deseas definir tu propia lógica de resolución de enlaces de modelos, puedes utilizar el método Route::bind. El closure que pases al método bind recibirá el valor del segmento URI y debería devolver la instancia de la clase que se debe inyectar en la ruta. Esta personalización debe realizarse en el método boot de la clase AppServiceProvider de tu aplicación.
use App\Models\User;
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::bind('user', function (string $value) {
return User::where('name', $value)->firstOrFail();
});
}
Como alternativa, puedes sobrescribir el método resolveRouteBinding en tu modelo Eloquent. Este método recibirá el valor del segmento URI y debería devolver la instancia de la clase que se debe inyectar en la ruta:
/**
* Retrieve the model for a bound value.
*
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}
Cuando una ruta utiliza el enlace implícito con ámbito, se utilizará el método resolveChildRouteBinding para resolver el modelo hijo del modelo.
/**
* Retrieve the child model for a bound value.
*
* @param string $childType
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveChildRouteBinding($childType, $value, $field)
{
return parent::resolveChildRouteBinding($childType, $value, $field);
}
Fallback Routes
Utilizando el método Route::fallback, puedes definir una ruta que se ejecutará cuando ninguna otra ruta coincida con la solicitud entrante. Normalmente, las solicitudes no gestionadas se renderizarán automáticamente con una página “404” a través del manejador de excepciones de tu aplicación. Sin embargo, al definir la ruta de fallback dentro de tu archivo routes/web.php, todos los middleware del grupo de middleware web se aplicarán a la ruta. También tienes la libertad de añadir middleware adicionales a esta ruta según sea necesario:
Route::fallback(function () {
// ...
});
⚠️ La ruta de fallback siempre debe ser la última ruta registrada en tu aplicación.
Rate Limiting
Laravel incluye servicios poderosos y personalizables de rate limit que puedes utilizar para restringir la cantidad de tráfico para una ruta específica o grupo de rutas. Para comenzar, debes definir configuraciones de rate limit que cumplan con las necesidades de tu aplicación.
Los rate limit se pueden definir dentro del método boot de la clase App\Providers\AppServiceProvider de tu aplicación.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}
Los rate limit se definen utilizando el método for del facade RateLimiter. El método for acepta un nombre de rate limit y un closure que devuelve la configuración del límite que debe aplicarse a las rutas asignadas al limitador de velocidad. Las configuraciones de límite son instancias de la clase Illuminate\Cache\RateLimiting\Limit. Esta clase contiene útiles métodos “builder” para que puedas definir rápidamente tu límite. El nombre del limitador de velocidad puede ser cualquier cadena que desees:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}
Si la solicitud entrante excede el límite de velocidad especificado, Laravel devolverá automáticamente una respuesta con un código de estado HTTP 429. Si deseas definir tu propia respuesta que debería ser devuelta por un límite de velocidad, puedes usar el método response:
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
return response('Custom response...', 429, $headers);
});
});
Como los callbacks del rate limit reciben la instancia entrante de la solicitud HTTP, puedes construir dinámicamente el límite de velocidad adecuado basado en la solicitud entrante o en el usuario autenticado:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});
Segmenting Rate Limits
A veces puede que desees segmentar los límites de velocidad por algún valor arbitrario. Por ejemplo, permitir que los usuarios accedan a una ruta dada 100 veces por minuto por dirección IP. Para lograr esto, puedes usar el método by al construir tu límite de velocidad:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});
Para ilustrar esta característica con otro ejemplo, podemos limitar el acceso a la ruta a 100 veces por minuto por ID de usuario autenticado o 10 veces por minuto por dirección IP para invitados:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
Multiple Rate Limits
Si es necesario, puedes devolver un array de límites de velocidad para una configuración dada de limitador de velocidad. Cada límite de velocidad se evaluará para la ruta según el orden en que estén colocados dentro del array:
Attaching Rate Limiters to Routes
Los limitadores de velocidad pueden ser adjuntados a rutas o grupos de rutas usando el middleware throttle. El middleware throttle acepta el nombre del limitador de velocidad que deseas asignar a la ruta:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
// ...
});
Route::post('/video', function () {
// ...
});
});
Throttling With Redis
Por defecto, el middleware throttle está mapeado a la clase Illuminate\Routing\Middleware\ThrottleRequests. Sin embargo, si estás usando Redis como el driver de caché de tu aplicación, puedes instruir a Laravel para que use Redis para gestionar el límite de velocidad. Para hacerlo, debes usar el método throttleWithRedis en el archivo bootstrap/app.php de tu aplicación. Este método mapea el middleware throttle a la clase Illuminate\Routing\Middleware\ThrottleRequestsWithRedis:
->withMiddleware(function (Middleware $middleware) {
$middleware->throttleWithRedis();
// ...
})
Form Method Spoofing
Los formularios HTML no admiten acciones PUT, PATCH o DELETE. Por lo tanto, al definir rutas PUT, PATCH o DELETE que se llaman desde un formulario HTML, deberás agregar un campo oculto _method al formulario. El valor enviado con el campo _method se utilizará como método de solicitud HTTP:
<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Para mayor comodidad, puedes usar la directiva Blade @method para generar el campo de entrada _method:
<form action="/example" method="POST">
@method('PUT')
@csrf
</form>
Accessing the Current Route
Puedes utilizar los métodos current, currentRouteName y currentRouteAction en el facade Route para acceder a información sobre la ruta que maneja la solicitud entrante:
use Illuminate\Support\Facades\Route;
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
Puedes consultar la documentación API tanto para la clase subyacente del facade Route como para la instancia de Route para revisar todos los métodos disponibles en las clases de enrutador y ruta.
Cross-Origin Resource Sharing (CORS)
Laravel puede responder automáticamente a las solicitudes HTTP OPTIONS de CORS con los valores que configures. Las solicitudes OPTIONS serán manejadas automáticamente por el middleware HandleCors, el cual está incluido automáticamente en la pila global de middleware de tu aplicación.
A veces, puede que necesites personalizar los valores de configuración de CORS para tu aplicación. Puedes hacerlo publicando el archivo de configuración cors usando el comando Artisan config:publish:
php artisan config:publish cors
Este comando colocará un archivo de configuración cors.php dentro del directorio config de tu aplicación.
Para obtener más información sobre CORS y los encabezados CORS, consulta la documentación web de MDN sobre CORS.
Route Caching
Cuando despliegues tu aplicación en producción, deberías aprovechar la caché de rutas de Laravel. Usar la caché de rutas disminuirá drásticamente el tiempo necesario para registrar todas las rutas de tu aplicación. Para generar una caché de rutas, ejecuta el comando Artisan route:cache:
php artisan route:cache
Después de ejecutar este comando, tu archivo de rutas en caché se cargará en cada solicitud. Recuerda que si agregas nuevas rutas, necesitarás generar una nueva caché de rutas. Por esta razón, deberías ejecutar el comando route:cache solo durante el despliegue de tu proyecto.
Puedes usar el comando route:clear para limpiar la caché de rutas:
php artisan route:clear