Rotas
Roteamento Básico
As rotas mais básicas do Laravel aceitam um URI e uma closure, fornecendo um método muito simples e expressivo de definir rotas e comportamentos sem arquivos de configuração de roteamento complicados:
use Illuminate\Support\Facades\Route;
Route::get('/greeting', function () {
return 'Hello World';
});
Arquivos de Rotas Padrão
Todas as rotas do Laravel são definidas em seus arquivos de rota, que estão localizados no diretório routes
. Esses arquivos são carregados automaticamente pelo Laravel usando a configuração especificada no arquivo bootstrap/app.php
de sua aplicação. O arquivo routes/web.php
define rotas que são para sua interface web. Essas rotas são atribuídas ao grupo de middleware web
, que fornece recursos como estado de sessão e proteção CSRF.
Para a maioria das aplicações, você começará definindo rotas em seu arquivo routes/web.php
. As rotas definidas em routes/web.php
podem ser acessadas digitando a URL da rota definida em seu navegador. Por exemplo, você pode acessar a seguinte rota navegando até http://example.com/user
em seu navegador:
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
Rotas de APIs
Se sua aplicação também oferecer uma API stateless, você pode habilitar o roteamento de API usando o comando Artisan install:api
:
php artisan install:api
O comando install:api
instala o Laravel Sanctum, que fornece um sistema robusto de autenticação por token de API, mas simples, que pode ser usado para autenticar consumidores de APIs de terceiros, SPAs ou aplicativos móveis. Além disso, o comando install:api
cria o arquivo routes/api.php
:
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
As rotas em routes/api.php
são stateless e são atribuídas ao grupo de middleware api
. Além disso, o prefixo de URI /api
é aplicado automaticamente a essas rotas, então você não precisa aplicá-lo manualmente a cada rota no arquivo. Você pode alterar o prefixo modificando o arquivo bootstrap/app.php
de sua aplicação:
->withRouting(
api: __DIR__.'/../routes/api.php',
apiPrefix: 'api/admin',
// ...
)
Métodos de Roteamento Disponíveis
O Router permite que você registre rotas que respondem a qualquer 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);
Às vezes, você pode precisar registrar uma rota que responda a vários verbos HTTP. Você pode fazer isso usando o método match
. Ou, você pode até mesmo registrar uma rota que responda a todos os verbos HTTP usando o método any
:
Route::match(['get', 'post'], '/', function () {
// ...
});
Route::any('/', function () {
// ...
});
Dica
Quando definir várias rotas que compartilham o mesmo URI, certifique-se de que as rotas com os métodos get
, post
, put
, patch
, delete
e options
sejam definidas antes das rotas com os métodos any
, match
e redirect
. Isso garante que a solicitação seja direcionada para a rota correta.
Injeção de Dependência
Você pode tipar qualquer dependência necessária por sua rota na assinatura do callback de sua rota. As dependências declaradas serão automaticamente resolvidas e injetadas no callback pelo container de serviços. Por exemplo, você pode tipar a classe Illuminate\Http\Request
para ter a solicitação HTTP atual injetada automaticamente em seu callback de rota:
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
// ...
});
Proteção CSRF
Lembre-se, qualquer formulário HTML apontando para rotas POST
, PUT
, PATCH
ou DELETE
que são definidas no arquivo de rotas web
devem incluir um campo de token CSRF. Caso contrário, a solicitação será rejeitada. Saiba mais sobre a proteção CSRF na documentação CSRF:
<form method="POST" action="/profile">
@csrf
...
</form>
Rotas de Redirecionamento
Se você estiver definindo uma rota que redireciona para outro URI, você pode usar o método Route::redirect
. Este método fornece um atalho para que você não precise definir uma rota completa ou controller para realizar um redirecionamento simples:
Route::redirect('/here', '/there');
Por padrão, Route::redirect
retorna um código de status 302
. Você pode personalizar o código de status usando o terceiro parâmetro opcional:
Route::redirect('/here', '/there', 301);
Ou, você pode usar o método Route::permanentRedirect
para retornar um código de status 301
:
Route::permanentRedirect('/here', '/there');
Atenção
Ao usar parâmetros de rota em rotas de redirecionamento, os seguintes parâmetros são reservados pelo Laravel e não podem ser usados: destination
e status
.
Rotas para Views
Se sua rota só precisa retornar uma view, você pode usar o método Route::view
. Assim como o método redirect
, este método fornece um atalho simples para que você não precise definir uma rota completa ou controller. O método view
aceita um URI como seu primeiro argumento e um nome de view como seu segundo argumento. Além disso, você pode fornecer um array associativo de dados para passar para a view como um terceiro argumento opcional:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
Atenção
Ao usar parâmetros de rota em rotas de view, os seguintes parâmetros são reservados pelo Laravel e não podem ser usados: view
, data
, status
e headers
.
Listando Suas Rotas
O comando Artisan route:list
fornece uma visão geral de todas as rotas definidas na aplicação:
php artisan route:list
Por padrão, os middleware de rota atribuídos a cada rota não serão exibidos na saída de route:list
; no entanto, você pode instruir o Laravel a exibir os middleware e os nomes de grupos de middleware adicionando a opção -v
ao comando:
php artisan route:list -v
Você também pode instruir o Laravel a mostrar apenas rotas que começam com um determinado URI:
php artisan route:list --path=api
Além disso, você pode instruir o Laravel a ocultar quaisquer rotas definidas por pacotes de terceiros fornecendo a opção --except-vendor
ao executar o comando route:list
:
php artisan route:list --except-vendor
Da mesma forma, você também pode instruir o Laravel a mostrar apenas rotas definidas por pacotes de terceiros fornecendo a opção --only-vendor
ao executar o comando route:list
:
php artisan route:list --only-vendor
Customização de Roteamento
Por padrão, as rotas de sua aplicação são configuradas e carregadas pelo arquivo 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();
No entanto, às vezes você pode querer definir um arquivo inteiramente novo para conter um subconjunto des rotas. Para fazer isso, você pode fornecer uma closure then
ao método withRouting
. Dentro desta closure, você pode registrar quaisquer rotas adicionais que sejam necessárias:
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'));
},
)
Ou, você pode até mesmo assumir o controle total sobre o registro de rotas fornecendo uma closure using
ao método withRouting
. Quando este argumento é passado, nenhuma rota HTTP será registrada pelo framework e você é responsável por registrar manualmente todas as rotas:
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'));
},
)
Parâmetros de Rota
Parâmetros Obrigatórios
Às vezes, você precisará capturar segmentos do URI dentro de sua rota. Por exemplo, você pode precisar capturar o ID de um usuário vindo da URL. Você pode fazer isso definindo parâmetros de rota:
Route::get('/user/{id}', function (string $id) {
return 'User '.$id;
});
Você pode definir quantos parâmetros de rota forem necessários:
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
// ...
});
Os parâmetros de rota são sempre envolvidos em chaves {}
e devem consistir de caracteres alfabéticos. Underscores (_
) também são aceitáveis nos nomes de parâmetros de rota. Os parâmetros de rota são injetados nos callbacks da rota/controllers com base em sua ordem - os nomes dos argumentos de callback/controller de rota não importam.
Parâmetros e Injeção de Dependência
Se sua rota tiver dependências que você deseja que o container de serviços do Laravel injete automaticamente no callback da rota, liste os parâmetros da rota após essas dependências:
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, string $id) {
return 'User '.$id;
});
Parâmetros Opcionais
Às vezes, você pode precisar especificar um parâmetro de rota que pode nem sempre estar presente na URI. Você pode fazer isso colocando um sinal de ?
após o nome do parâmetro. Certifique-se de dar um valor padrão à variável correspondente da rota:
Route::get('/user/{name?}', function (?string $name = null) {
return $name;
});
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});
Expressões Regulares
Você pode restringir o formato de seus parâmetros de rota usando o método where
em uma instância de rota. O método where
aceita o nome do parâmetro e uma expressão regular definindo como o parâmetro deve ser restrito:
Route::get('/user/{name}', function (string $name) {
// ...
})->where('name', '[A-Za-z]+'); // Apenas letras
Route::get('/user/{id}', function (string $id) {
// ...
})->where('id', '[0-9]+'); // Apenas números
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
Para conveniência, alguns padrões de expressão regular comumente usados têm métodos auxiliares que permitem adicionar rapidamente restrições às suas rotas:
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());
Se a solicitação de entrada não corresponder às restrições de padrão da rota, uma resposta HTTP 404 será retornada.
Condições de Parâmetro Globais
Se você deseja que um parâmetro de rota seja sempre restrito por uma determinada expressão regular, você pode usar o método pattern
. Você deve definir esses padrões no método boot
da classe App\Providers\AppServiceProvider
de sua aplicação:
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}
Uma vez que o padrão tenha sido definido, ele é automaticamente aplicado a todas as rotas que usam o parâmetro com o nome definido.
Route::get('/user/{id}', function (string $id) {
// Só será executado se {id} for numérico...
});
Barras Invertidas Codificadas
O componente de roteamento do Laravel permite que todos os caracteres, exceto /
, estejam presentes nos valores dos parâmetros de rota. Você deve permitir explicitamente /
para fazer parte de seu espaço reservado usando uma expressão regular de condição where
:
Route::get('/search/{search}', function (string $search) {
return $search;
})->where('search', '.*');
Atenção
As barras invertidas codificadas são suportadas apenas no último segmento de rota.
Rotas Nomeadas
Rotas nomeadas permitem a geração conveniente de URLs ou redirecionamentos para rotas específicas. Você pode especificar um nome para uma rota encadeando o método name
na definição da rota:
Route::get('/user/profile', function () {
// ...
})->name('profile');
Você também pode especificar nomes de rota para ações de controller:
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');
Atenção
Os nomes de rotas devem sempre ser únicos.
Gerando URLs para Rotas Nomeadas
Uma vez que você atribuiu um nome a uma rota específica, você pode usar o nome da rota ao gerar URLs ou redirecionamentos via os helpers route
e redirect
do Laravel:
// Gerando URLs...
$url = route('profile');
// Gerando redirecionamentos...
return redirect()->route('profile');
return to_route('profile');
Se a rota nomeada definir parâmetros, você pode passar os parâmetros como segundo argumento para a função route
. Os parâmetros fornecidos serão automaticamente inseridos na URL gerada em suas posições corretas:
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1]);
Você pode passar parâmetros adicionais no array, esses pares chave/valor serão automaticamente adicionados à string de consulta da URL gerada:
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yes
Dica
Em alguns casos, você pode desejar especificar valores padrão para parâmetros de URL. Para fazer isso, você pode usar o método URL::defaults
.
Inspeção da Rota Atual
Se você deseja verificar se a request atual foi direcionada para uma rota nomeada específica, pode usar o método named
em uma instância de rota. Por exemplo, você pode verificar o nome da rota atual em um middleware de rota:
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')) {
// Se a rota atual for nomeada "profile"...
}
return $next($request);
}
Grupos de Rotas
Os grupos de rotas permitem que você compartilhe atributos de rota, como middleware, em um grande número de rotas sem precisar definir esses atributos em cada rota individualmente.
Os grupos aninhados tentam "mesclar" inteligentemente os atributos com seu grupo pai. Os middleware e condições where
são mesclados enquanto os nomes e prefixos são anexados. Delimitadores de namespace e barras invertidas em prefixos de URI são adicionados automaticamente quando apropriado.
Middleware
Para atribuir middleware a todas as rotas dentro de um grupo, você pode usar o método middleware
antes de definir o grupo. Os middleware são executados na ordem em que são listados no array:
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});
Controllers
Se um grupo de rotas utilizar o mesmo controller, você pode usar o método controller
para definir um controller comum para todas as rotas dentro do grupo. Em seguida, ao definir as rotas, você só precisa fornecer o método do controller que elas invocam:
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
Rotas de Subdomínio
Os grupos de rotas também podem ser usados para lidar com roteamento de subdomínios. Você pode atribuir subdomínios a parâmetros de rota da mesma forma que faz com URIs de rota. Isso permite capturar uma parte do subdomínio para uso em sua rota / controller. Para especificar o subdomínio, chame o método domain
antes de definir o grupo:
Route::domain('{account}.example.com')->group(function () {
Route::get('/user/{id}', function (string $account, string $id) {
// ...
});
});
Atenção
Para garantir que suas rotas de subdomínio sejam acessíveis, registre as rotas de subdomínio antes das rotas de domínio raiz. Isso evita que as rotas de domínio raiz sobrescrevam as rotas de subdomínio que têm o mesmo caminho de URI.
Prefixos de Rota
O método prefix
pode ser usado para prefixar cada rota no grupo com um URI fornecido. Por exemplo, você pode querer prefixar todos os URIs de rota dentro do grupo com admin
:
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
Prefixos de Nome de Rota
O método name
pode ser usado para prefixar cada nome de rota no grupo com uma string fornecida. Por exemplo, você pode querer prefixar os nomes de todas as rotas no grupo com admin
. A string fornecida é prefixada ao nome da rota exatamente como é especificado, então certifique-se de fornecer o caractere de ponto final .
no prefixo:
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
Route Model Binding
Ao injetar um ID de um model em uma rota ou ação de controller, você frequentemente consulta o banco de dados para recuperar a instância do modelo que corresponde a esse ID. O route model binding do Laravel fornece uma maneira conveniente de injetar automaticamente as instâncias do model diretamente em suas rotas. Por exemplo, em vez de injetar o ID de um usuário, você pode injetar a instância inteira do modelo User
que corresponde ao ID fornecido.
Binding Implícito
O Laravel resolve automaticamente os models Eloquent definidos em rotas ou ações de controller cujo o nome da variável tipada corresponde a um nome de parâmetro de rota. Por exemplo:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
});
Uma vez que a variável $user
é tipada como o model Eloquent App\Models\User
e o nome da variável corresponde ao segmento de URI {user}
, o Laravel injetará automaticamente a instância do modelo que tem um ID correspondente ao valor correspondente da URI da solicitação. Se uma instância de modelo correspondente não for encontrada no banco de dados, uma resposta HTTP 404 será gerada automaticamente.
Claro, o binding implícito também é possível ao usar métodos de controller. Novamente, observe que o segmento de URI {user}
corresponde à variável $user
no controller que contém um tipo de dica 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, o binding implícito de models não recuperará models que foram soft deleted. No entanto, você pode instruir o binding implícito a recuperar esses models encadeando o método withTrashed
na definição da rota:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();
Customizando a Chave Padrão
Às vezes, você pode desejar resolver models Eloquent usando uma coluna diferente de id
. Para fazer isso, você pode especificar a coluna na definição do parâmetro de rota:
use App\Models\Post;
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});
Se você deseja que o model binding sempre use uma coluna de banco de dados diferente de id
ao recuperar um determinado model, você pode substituir o método getRouteKeyName
no model:
/**
* Get the route key for the model.
*/
public function getRouteKeyName(): string
{
return 'slug';
}
Chaves Personalizadas e Escopo
Quando você deseja vincular implicitamente vários models em uma única definição de rota, você pode desejar limitar o segundo model de forma que ele seja um filho do model. Por exemplo, considere esta rota que recupera uma postagem de blog por slug para um usuário específico:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
Ao usar um binding implícito com chave personalizada como um parâmetro de rota aninhado, o Laravel automaticamente limitará a consulta para recuperar o modelo aninhado por seu pai usando convenções para adivinhar o nome do relacionamento no pai. Neste caso, será assumido que o modelo User
tem um relacionamento chamado posts
(a forma plural do nome do parâmetro de rota) que pode ser usado para recuperar o modelo Post
.
Se desejar, você pode instruir o Laravel a limitar os bindings "filhos" mesmo quando uma chave personalizada não é fornecida. Para fazer isso, você pode invocar o método scopeBindings
ao definir sua rota:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();
Ou, você pode instruir um grupo inteiro de rotas a usar bindings limitados:
Route::scopeBindings()->group(function () {
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
});
});
Da mesma forma, você pode instruir explicitamente o Laravel a não limitar os bindings invocando o método withoutScopedBindings
:
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
})->withoutScopedBindings();
Customizando o Comportamento de Models Ausentes
Normalmente, uma resposta HTTP 404 será gerada se um model vinculado implicitamente não for encontrado. No entanto, você pode personalizar esse comportamento chamando o método missing
ao definir sua rota. O método missing
aceita uma closure que será chamada se um model vinculado não puder ser encontrado:
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');
});
Binding Implícito com Enums
O PHP 8.1 trouxe suporte para Enums. Para complementar esse recurso, o Laravel permite que você faça tipe-hint de um Enum com valor em sua definição de rota e o Laravel só invocará a rota se o segmento de rota correspondente a um valor Enum válido. Caso contrário, uma resposta HTTP 404 será retornada automaticamente. Por exemplo, dado o seguinte Enum:
Dica
tipe-hint é um termo usado para descrever a prática de declarar o tipo de uma variável, parâmetro ou retorno de função em uma linguagem de programação.
<?php
namespace App\Enums;
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}
Você pode definir uma rota que só será invocada se o segmento de rota {category}
for fruits
ou people
. Caso contrário, o Laravel retornará uma resposta HTTP 404:
use App\Enums\Category;
use Illuminate\Support\Facades\Route;
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});
Binding Explícito
Você não é obrigado a usar a resolução de models implícita. Você também pode definir explicitamente como os parâmetros de rota correspondem aos models. Para registrar um binding explícito, use o método model
do Route
para especificar uma classe para um determinado parâmetro. Você deve definir seus bindings de models explícitos no início do método boot
da sua classe AppServiceProvider
:
use App\Models\User;
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::model('user', User::class);
}
Em seguida, defina uma rota que contenha um parâmetro {user}
:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
// ...
});
Uma vez que você vinculou todos os parâmetros {user}
ao model App\Models\User
, uma instância dessa classe será injetada na rota. Portanto, por exemplo, uma solicitação para users/1
injetará a instância User
do banco de dados que tem um ID de 1
.
Se uma instância de model correspondente não for encontrada no banco de dados, uma resposta HTTP 404 será gerada automaticamente.
Customizando a Lógica de Resolução
Se desejar definir sua própria lógica de resolução de model binding, você pode usar o método Route::bind
. A closure que você passa para o método bind
receberá o valor do segmento de URI e deve retornar a instância da classe que deve ser injetada na rota. Novamente, essa personalização deve ocorrer no método boot
da classe AppServiceProvider
de sua aplicação:
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, você pode substituir o método resolveRouteBinding
em seu model Eloquent. Este método receberá o valor do segmento de URI e deve retornar a instância da classe que deve ser injetada na rota:
/**
* 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();
}
Se uma rota estiver utilizando scoping de binding implícito de model, o método resolveChildRouteBinding
será usado para resolver o binding filho do model pai:
/**
* 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);
}
Rotas de Fallback
Usando o método Route::fallback
, você pode definir uma rota que será executada quando nenhuma outra rota corresponder à solicitação recebida. Tipicamente, solicitações não tratadas renderizarão automaticamente uma página "404" via o manipulador de exceções de sua aplicação. No entanto, como você normalmente definiria a rota fallback
dentro do arquivo routes/web.php
, todos os middleware no grupo de middleware web
serão aplicados à rota. Você é livre para adicionar middleware adicional a esta rota conforme necessário:
Route::fallback(function () {
// ...
});
Atenção
A rota de fallback deve sempre ser a última rota registrada por sua aplicação.
Limitadores de Requisições (Rate Limiting)
Definindo Limitadores de Requisições
O Laravel inclui serviços de limitação de requisições poderosos e personalizáveis que você pode utilizar para restringir a quantidade de tráfego para uma determinada rota ou grupo de rotas. Para começar, você deve definir configurações de limitador de taxa que atendam às necessidades de sua aplicação.
Os limitadores de requisições podem ser definidos no método boot
da classe App\Providers\AppServiceProvider
:
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());
});
}
Os limitadores de requisições são definidos usando o método for
da facade RateLimiter
. O método for
aceita um nome de limitador de requisições e uma closure que retorna a configuração de limite que deve ser aplicada às rotas atribuídas ao limitador de requisições. As configurações de limite são instâncias da classe Illuminate\Cache\RateLimiting\Limit
. Esta classe contém métodos "builder" úteis para que você possa definir rapidamente seu limite. O nome do limitador de requisições pode ser qualquer string que você desejar.
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);
});
}
Se a requisição exceder o limite especificado, uma resposta com um código de status HTTP 429 será automaticamente retornada pelo Laravel. Se você deseja definir sua própria resposta que deve ser retornada por um limite de taxa, você pode usar o 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);
});
});
Uma vez que os callbacks de limitador de requisições recebem a instância de requisição HTTP de entrada, você pode construir o limite apropriado dinamicamente com base na requisição de entrada ou usuário autenticado:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});
Segmentando Limitadores de Requisições
Às vezes, você pode desejar segmentar limitadores de requisições por algum valor arbitrário. Por exemplo, você pode desejar permitir que os usuários acessem uma determinada rota 100 vezes por minuto por endereço IP. Para fazer isso, você pode usar o método by
ao construir seu limite de taxa:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});
Para ilustrar esse recurso usando outro exemplo, podemos limitar o acesso à rota a 100 vezes por minuto por ID de usuário autenticado ou 10 vezes por minuto por endereço IP para convidados:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
Múltiplos Limitadores de Requisições
Se necessário, você pode retornar um array de limites para uma determinada configuração de limitador. Cada limite será avaliado para a rota com base na ordem em que são colocados no array:
RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});
Se você estiver atribuindo múltiplos limites segmentados por valores by
idênticos, você deve garantir que cada valor by
seja único. A maneira mais fácil de alcançar isso é prefixar os valores fornecidos ao método by
:
RateLimiter::for('uploads', function (Request $request) {
return [
Limit::perMinute(10)->by('minute:'.$request->user()->id),
Limit::perDay(1000)->by('day:'.$request->user()->id),
];
});
Associando Limitadores de Requisições às Rotas
Os limitadores de requisições podem ser anexados a rotas ou grupos de rotas usando o middleware throttle
. O middleware throttle
aceita o nome do limitador de requisições que você deseja atribuir à rota:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
// ...
});
Route::post('/video', function () {
// ...
});
});
Limitando Requisições com Redis
Por padrão, o middleware throttle
é mapeado para a classe Illuminate\Routing\Middleware\ThrottleRequests
. No entanto, se você estiver usando o Redis como driver de cache de sua aplicação, você pode instruir o Laravel a usar o Redis. Para fazer isso, você deve usar o método throttleWithRedis
no arquivo bootstrap/app.php
de sua aplicação. Este método mapeia o middleware throttle
para a classe Illuminate\Routing\Middleware\ThrottleRequestsWithRedis
:
->withMiddleware(function (Middleware $middleware) {
$middleware->throttleWithRedis();
// ...
})
Simulação de Métodos em Formulários
Formulários HTML não suportam ações PUT
, PATCH
ou DELETE
. Portanto, ao definir rotas PUT
, PATCH
ou DELETE
que são chamadas de um formulário HTML, você precisará adicionar um campo oculto _method
ao formulário. O valor enviado com o campo _method
será usado como o método de solicitação HTTP:
<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Para facilitar, você pode usar a diretiva Blade @method
para gerar o campo _method
:
<form action="/example" method="POST">
@method('PUT')
@csrf
</form>
Acessando a Rota Atual
Você pode usar os métodos current
, currentRouteName
e currentRouteAction
na facade Route
para acessar informações sobre a rota que está lidando com a solicitação recebida:
use Illuminate\Support\Facades\Route;
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
Você pode consultar a documentação da API para a classe da facade Route e instância da rota para revisar todos os métodos disponíveis nas classes de roteador e rota.
Cross-Origin Resource Sharing (CORS)
O Laravel pode responder automaticamente a requisições HTTP CORS OPTIONS
com valores que você configura. As solicitações OPTIONS
serão automaticamente tratadas pelo middleware HandleCors
que é automaticamente incluído no grupo de middlewares globais.
Às vezes, você pode precisar personalizar os valores de configuração CORS para sua aplicação. Você pode fazer isso publicando o arquivo de configuração cors
usando o comando Artisan config:publish
:
php artisan config:publish cors
Este comando adiciona um arquivo de configuração cors.php
no diretório config
de sua aplicação.
Dica
Para obter mais informações sobre CORS e cabeçalhos CORS, consulte a documentação web MDN sobre CORS.
Cache de Rotas
Ao subir sua aplicação para produção, você deve aproveitar o cache de rotas do Laravel. Usar o cache de rotas reduz drasticamente o tempo necessário para registrar todas as rotas de sua aplicação. Para gerar um cache de rotas, execute o comando Artisan route:cache
:
php artisan route:cache
Após executar este comando, seu arquivo de rotas em cache será carregado em todas as requisições. Lembre-se, se você adicionar novas rotas, precisará gerar um novo cache de rotas. Por conta disso, você só deve executar o comando route:cache
durante o deploy de seu projeto.
Você pode usar o comando route:clear
para limpar o cache de rotas:
php artisan route:clear