Explicação Detalhada do Sistema de Rotas do Laravel
Rotas são a "recepção" do Laravel—toda requisição HTTP primeiro passa por aqui antes de ser encaminhada ao método do controlador correspondente.
1. O Que Você Vai Aprender
- Rotas Básicas: Route::get/post/put/patch/delete
- Parâmetros de Rota e Restrições com Expressões Regulares
- Agrupamento de rotas: middleware/prefixo/nome/domínio
- Nomenclatura de Rotas e Geração de URL
- Rotas de API e Route::apiResource()
2. Uma História Real de um Gerente de Produto
(1) Problema: Estruturas de URL Caóticas Causam um Desastre de SEO
Alice projetou mais de 30 páginas para o ShopMetrics, mas a convenção de nomenclatura das URLs era completamente caótica: /shop_view.php?id=5, /admin-users-list e /api/getData estavam todos misturados. O crawler do Google era extremamente ineficiente, e quando os usuários compartilhavam links, a barra de endereços exibia uma sequência de parâmetros com pontos de interrogação. Quando Bob reestruturou o backend e alterou uma única URL, todas as 15 instâncias codificadas no frontend retornaram erros 404.
(2) Soluções para Rotas do Laravel
O roteamento do Laravel usa sintaxe declarativa para definir regras de URL, suportando nomenclatura, agrupamento e restrições de parâmetros; alterações feitas em um local entram em vigor globalmente automaticamente.
// routes/web.php — Rotas limpas, nomeadas e RESTful
Route::get('/shops/{slug}', [ShopController::class, 'show'])
->name('shops.show')
->where('slug', '[a-z0-9-]+');
// Gerar URL pelo nome — nunca codifique
$url = route('shops.show', ['slug' => 'alice-store']);
// => /shops/alice-store
(3) Resultado
Alice padronizou as regras de URL do ShopMetrics usando rotas nomeadas, resultando em um aumento de 30% nos rankings de SEO. Quando Bob reestruturou as URLs, precisou apenas atualizar as definições de rota; o route() do frontend gerou automaticamente as novas URLs, resultando em zero erros 404.
3. Rotas Básicas
(1) Rotas por Verbo HTTP
O Laravel fornece um método de rota correspondente para cada verbo HTTP:
// routes/web.php
Route::get('/shops', [ShopController::class, 'index']);
Route::post('/shops', [ShopController::class, 'store']);
Route::put('/shops/{id}', [ShopController::class, 'update']);
Route::patch('/shops/{id}', [ShopController::class, 'updateStatus']);
Route::delete('/shops/{id}', [ShopController::class, 'destroy']);
| Verbo HTTP | Finalidade | Idempotência | Operações Típicas |
|---|---|---|---|
| GET | Recuperar Recurso | ✅ | Lista/Detalhes |
| POST | Criar Recurso | ❌ | Adicionar |
| PUT | Atualização Completa | ✅ | Substituir |
| PATCH | Atualização Parcial | ✅ | Alteração de Status |
| DELETE | Excluir Recurso | ✅ | Excluir |
(2) Rotas "match" e "any"
// Corresponder a múltiplos verbos
Route::match(['get', 'post'], '/shops/search', [ShopController::class, 'search']);
// Qualquer verbo
Route::any('/fallback', [FallbackController::class, 'handle']);
(1) ▶ Exemplo: Definições de Rotas Básicas do ShopMetrics
// routes/web.php
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/about', [AboutController::class, 'index'])->name('about');
Route::get('/pricing', [PricingController::class, 'index'])->name('pricing');
Route::get('/contact', [ContactController::class, 'create'])->name('contact.create');
Route::post('/contact', [ContactController::class, 'store'])->name('contact.store');
Saída:
// Execução bem-sucedida
4. Parâmetros e Restrições de Rotas
(1) Parâmetros Obrigatórios
Route::get('/shops/{id}', [ShopController::class, 'show']);
Route::get('/tenants/{tenant}/shops/{shop}', [ShopController::class, 'showForTenant']);
(2) Parâmetros Opcionais
Route::get('/reports/{type?}', [ReportController::class, 'index']);
// /reports → type = null
// /reports/sales → type = 'sales'
(3) Expressões Regulares
// Apenas ID numérico
Route::get('/shops/{id}', [ShopController::class, 'show'])
->where('id', '[0-9]+');
// Formato slug: minúsculas, números, hifens
Route::get('/shops/{slug}', [ShopController::class, 'showBySlug'])
->where('slug', '[a-z0-9-]+');
// Múltiplas restrições
Route::get('/tenants/{tenant}/orders/{id}', [OrderController::class, 'show'])
->where(['tenant' => '[a-z0-9-]+', 'id' => '[0-9]+']);
| Método de Restrição | Uso | Descrição |
|---|---|---|
where() |
Expressão regular de parâmetro único | Mais flexível |
whereNumber() |
Apenas números | Equivalente a where('id', '[0-9]+') |
whereAlpha() |
Apenas letras | Equivalente a where('name', '[a-zA-Z]+') |
whereAlphaNumeric() |
Letras + Números | Equivalente a where('name', '[a-zA-Z0-9]+') |
whereUuid() |
Formato UUID | Validação automática UUID v4 |
(1) ▶ Exemplo: Rotas do ShopMetrics com Restrições
// routes/web.php
Route::get('/shops/{id}', [ShopController::class, 'show'])
->whereNumber('id');
Route::get('/categories/{slug}', [CategoryController::class, 'show'])
->where('slug', '[a-z0-9-]+');
Route::get('/tenants/{tenant}/dashboard', [DashboardController::class, 'index'])
->where('tenant', '[a-z0-9-]+');
Saída:
// Execução bem-sucedida
5. Grupos de Rotas
O agrupamento de rotas permite que múltiplas rotas compartilhem configurações (middleware, prefixos, namespaces, etc.), evitando duplicação de código.
(1) Agrupamento por Middleware
Route::middleware(['auth', 'tenant.resolve'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/shops', [ShopController::class, 'index']);
Route::get('/orders', [OrderController::class, 'index']);
});
(2) Agrupamento por Prefixo
Route::prefix('admin')->group(function () {
Route::get('/users', [AdminUserController::class, 'index']);
Route::get('/settings', [AdminSettingController::class, 'index']);
// URL completa: /admin/users, /admin/settings
});
(3) Agrupamento por Nome
Route::name('admin.')->group(function () {
Route::get('/users', [AdminUserController::class, 'index'])->name('users');
// Nome da rota: admin.users
});
(4) Combinação e Agrupamento
Route::prefix('admin')
->middleware(['auth', 'admin'])
->name('admin.')
->group(function () {
Route::get('/users', [AdminUserController::class, 'index'])->name('users');
Route::get('/plans', [AdminPlanController::class, 'index'])->name('plans');
// URL: /admin/users, nome: admin.users
});
(1) ▶ Exemplo: Grupos de Rotas Multi-tenant do ShopMetrics
// routes/web.php — Rotas com consciência de tenant
Route::middleware(['auth', 'tenant.resolve'])->prefix('/{tenant}')->group(function () {
Route::get('/dashboard', [TenantDashboardController::class, 'index'])
->name('tenant.dashboard');
Route::resource('/shops', ShopController::class);
Route::resource('/orders', OrderController::class);
Route::resource('/products', ProductController::class);
});
Saída:
// Execução bem-sucedida
6. Nomenclatura de Rotas e Geração de URL
(1) Rotas Nomeadas
Route::get('/shops/{id}', [ShopController::class, 'show'])
->name('shops.show');
(2) Gerar uma URL
// Em templates Blade ou controladores
$url = route('shops.show', ['id' => 5]);
// => http://shopmetrics.test/shops/5
// Com parâmetros de consulta
$url = route('shops.index', ['sort' => 'name', 'page' => 2]);
// => http://shopmetrics.test/shops?sort=name&page=2
| Função | Finalidade | Exemplo |
|---|---|---|
route() |
Gerar URL de rota nomeada | route('shops.show', 5) |
url() |
Gerar URL absoluta | url('/shops') |
action() |
Gerar baseado no método do controlador | action([ShopController::class, 'show'], 5) |
(1) ▶ Exemplo: Usando Rotas Nomeadas no Blade
<a href="{{ route('shops.show', $shop->id) }}">{{ $shop->name }}</a>
<form action="{{ route('shops.update', $shop->id) }}" method="POST">
@method('PUT')
@csrf
<!-- campos do formulário -->
</form>
Saída:
// Execução bem-sucedida
7. Rotas de API
routes/api.php Usado exclusivamente para rotas de API; adiciona automaticamente o prefixo /api.
(1) Rota apiResource
// routes/api.php
use App\Http\Controllers\Api\ShopController;
Route::apiResource('shops', ShopController::class);
// Gera:
// GET /api/shops → index
// POST /api/shops → store
// GET /api/shops/{shop} → show
// PUT /api/shops/{shop} → update
// DELETE /api/shops/{shop} → destroy
| Método | apiResource | resource |
|---|---|---|
| index | ✅ | ✅ |
| create | ❌ | ✅ |
| store | ✅ | ✅ |
| show | ✅ | ✅ |
| edit | ❌ | ✅ |
| update | ✅ | ✅ |
| destroy | ✅ | ✅ |
(2) Versionamento de API
Route::prefix('v1')->group(function () {
Route::apiResource('shops', Api\V1\ShopController::class);
Route::apiResource('orders', Api\V1\OrderController::class);
});
Route::prefix('v2')->group(function () {
Route::apiResource('shops', Api\V2\ShopController::class);
});
(1) ▶ Exemplo: Blueprint de Rotas de API do ShopMetrics
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::prefix('v1')->name('api.v1.')->group(function () {
Route::apiResource('tenants.shops', Api\V1\TenantShopController::class);
Route::apiResource('shops.orders', Api\V1\ShopOrderController::class);
Route::apiResource('products', Api\V1\ProductController::class);
Route::get('analytics/overview', [Api\V1\AnalyticsController::class, 'overview']);
Route::post('reports/generate', [Api\V1\ReportController::class, 'generate']);
});
});
Saída:
// Execução bem-sucedida
8. Processo de Correspondência de Rotas
flowchart LR
A[Requisição HTTP] --> B{Rota correspondente?}
B -->|Sim| C[Extrair Parâmetros]
C --> D[Executar Middleware]
D --> E[Chamar Método do Controlador]
E --> F[Retornar Resposta]
B -->|Não| G[Rota Fallback]
G --> H[404 Não Encontrado]
9. Exemplo Completo: Blueprint de Rotas Completo do ShopMetrics
// ============================================
// Completo: Rotas completas do ShopMetrics
// Abrange: rotas web, rotas api, grupos, restrições
// ============================================
// routes/web.php
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/pricing', [PricingController::class, 'index'])->name('pricing');
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::resource('shops', ShopController::class)->whereNumber('shop');
Route::resource('shops.orders', OrderController::class)->shallow();
Route::post('/shops/{shop}/logo', [ShopLogoController::class, 'update'])
->name('shops.logo.update');
});
// routes/api.php
Route::prefix('v1')->middleware('auth:sanctum')->group(function () {
Route::apiResource('shops', Api\ShopController::class);
Route::apiResource('shops.products', Api\ProductController::class)->shallow();
Route::apiResource('shops.orders', Api\OrderController::class)->shallow();
Route::get('analytics/summary', [Api\AnalyticsController::class, 'summary']);
Route::post('reports/generate', [Api\ReportController::class, 'generate']);
});
❓ Perguntas Frequentes
web.php aplicam automaticamente o grupo de middleware web (Session, CSRF, criptografia de cookies), sendo adequado para requisições de páginas; rotas em api.php aplicam automaticamente o grupo de middleware API (limitação de taxa throttle), e as URLs são automaticamente prefixadas com /api, sendo adequado para requisições de API.Route::resource, e quando devo definir rotas manualmente?resource/apiResource; para operações não padronizadas (como busca, exportação e operações em lote), defina rotas adicionais manualmente.route() são atualizadas automaticamente. Com URLs codificadas, é necessário fazer uma busca e substituição global a cada alteração, o que facilita perder algumas instâncias.php artisan route:cache.php artisan route:list para listar todas as rotas, incluindo método, URI, nome e middleware. Adicione --path=shops para filtrar rotas por um prefixo específico.📖 Resumo
- O Laravel fornece métodos de roteamento para cada verbo HTTP: GET, POST, PUT, PATCH e DELETE
- Parâmetros de rota podem ser obrigatórios ou opcionais; você pode usar
where()para adicionar restrições com expressões regulares - O agrupamento de rotas permite que múltiplas rotas compartilhem middleware, prefixos e namespaces
- Use rotas nomeadas em conjunto com a função
route()para desacoplar URLs do código - apiResource: Gera automaticamente rotas de API RESTful (excluindo create/edit)
- Cache de rotas (route:cache) pode melhorar significativamente o desempenho de correspondência de um grande número de rotas
📝 Exercícios
-
Exercício Básico (⭐): Defina as seguintes rotas para o ShopMetrics: Página inicial (GET /), Página Sobre (GET /about) e Página de Contato (GET+POST /contact). Use rotas nomeadas e verifique se estão acessíveis no navegador.
-
Exercício Avançado (⭐⭐): Use grupos de rotas para projetar um blueprint de rotas da API v1 para o ShopMetrics, incluindo três apiResources—shops, products e orders—junto com middleware de autenticação e o prefixo /api/v1.
-
Desafio (⭐⭐⭐): Implemente o agrupamento de rotas multi-tenant
/{tenant}/*. Escreva um middleware TenantResolve para analisar o tenant a partir da URL e injetá-lo no Request, garantindo que todas as sub-rotas possam recuperar o tenant atual via$request->tenant().



