Capítulo 5.5: Roteamento para Páginas Web
Tempo de estudo: 40 minutos
1. routes/web.php
vs routes/api.php
: Dois Painéis de Controle Diferentes
É importante reforçar novamente a diferença fundamental:
Característica | routes/web.php (Painel Web) |
routes/api.php (Painel API) |
---|---|---|
Tarefa Principal | Exibição de páginas HTML, processamento de formulários | Fornecimento de dados em formato JSON para outras aplicações |
Estado (State) | Stateful (com estado) — usa sessões e cookies | Stateless (sem estado) — cada requisição é independente |
Middleware padrão | web (inclui sessões, proteção CSRF, criptografia de cookies) |
api (inclui "throttling" — limitação de frequência de requisições) |
Prefixo da URL | Nenhum (raiz do seu site) | /api/ (configurável em RouteServiceProvider ) |
Autenticação | Geralmente via sessões (Login/Senha) | Geralmente via tokens (Sanctum, Passport) |
Trabalhamos com routes/web.php
para construir a interface para um ser humano.
2. Rotas de Recurso para a Web
Similar a Route::apiResource
, para a web existe Route::resource
. Ele cria rotas para o ciclo CRUD completo, incluindo páginas para exibir formulários de criação e edição.
Vamos criar um conjunto completo de rotas para gerenciar nossos planetas através da interface web.
Passo 1: Criamos a rota em routes/web.php
Comente ou exclua as rotas antigas para /planets
e substitua-as por uma única linha:
use App\Http\Controllers\Web\PlanetPageController;
// Route::get('/planets', [PlanetPageController::class, 'index']);
// Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);
Route::resource('planets', PlanetPageController::class);
Passo 2: Verificamos o que foi criado
Execute no terminal o comando php artisan route:list --except-vendor
:
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| GET|HEAD | planets | planets.index | ...\PlanetPageController@index | web |
| POST | planets | planets.store | ...\PlanetPageController@store | web |
| GET|HEAD | planets/create | planets.create | ...\PlanetPageController@create | web |
| GET|HEAD | planets/{planet} | planets.show | ...\PlanetPageController@show | web |
| PUT|PATCH | planets/{planet} | planets.update | ...\PlanetPageController@update | web |
| DELETE | planets/{planet} | planets.destroy | ...\PlanetPageController@destroy | web |
| GET|HEAD | planets/{planet}/edit | planets.edit | ...\PlanetPageController@edit | web |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
Route::resource
criou 7 rotas para nós, incluindo:
planets.create
(GET/planets/create
): página com formulário de criação.planets.store
(POST/planets
): processamento deste formulário.planets.edit
(GET/planets/{planet}/edit
): página com formulário de edição.planets.update
(PUT/PATCH/planets/{planet}
): processamento do formulário de edição.planets.destroy
(DELETE/planets/{planet}
): exclusão do recurso.
3. Rotas Nomeadas: Convenientes "Coordenadas Cósmicas"
Observe a coluna Name
. O Laravel atribuiu automaticamente a cada rota um nome único (por exemplo, planets.index
). Usar nomes em vez de URLs hardcoded é a melhor prática.
Por quê? Se você decidir alterar a URL de /planets
para /worlds
, não precisará procurar e alterar todos os links em seus templates. Você simplesmente o altera em um único lugar — no arquivo de rotas, e os nomes permanecem os mesmos.
Exemplo de uso no Blade:
Antes escrevíamos assim:
Agora escreveremos assim, usando o helper route()
:
route('planets.show', ...)
— gera a URL para a rota com o nomeplanets.show
.['planet' => $planet->id]
— passa os parâmetros necessários para a URL. O Laravel irá preencher o ID em{planet}
. Você pode até passar o modelo completo:['planet' => $planet]
.
4. Implementação dos Métodos Faltantes no Controller
Route::resource
criou as rotas, mas precisamos criar os métodos correspondentes em PlanetPageController
nós mesmos.
Abra app/Http/Controllers/Web/PlanetPageController.php
e os adicionaremos.
<?php
use Illuminate\Http\Request; // <-- Adicionar
class PlanetPageController extends Controller
{
// index() e show() nós já temos
/**
* Mostra o formulário para criar um novo planeta.
*/
public function create()
{
return view('planets.create'); // Apenas retornamos a view com o formulário
}
/**
* Salva um novo planeta no banco de dados.
*/
public function store(Request $request)
{
// Validação dos dados do formulário
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'solar_system' => 'required|string|max:100',
// ... outras regras
]);
Planet::create($validated);
// Redirecionamos o usuário para a página da lista com uma mensagem de sucesso
return redirect()->route('planets.index')->with('success', 'Planeta criado com sucesso!');
}
/**
* Mostra o formulário para editar um planeta.
*/
public function edit(Planet $planet)
{
return view('planets.edit', ['planet' => $planet]);
}
/**
* Atualiza os dados do planeta no banco de dados.
*/
public function update(Request $request, Planet $planet)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets,name,' . $planet->id,
'solar_system' => 'required|string|max:100',
]);
$planet->update($validated);
return redirect()->route('planets.show', $planet)->with('success', 'Dados do planeta atualizados!');
}
/**
* Exclui um planeta.
*/
public function destroy(Planet $planet)
{
$planet->delete();
return redirect()->route('planets.index')->with('success', 'Planeta removido.');
}
}
redirect()->route(...)
— redireciona o usuário para outra rota nomeada.->with('success', '...')
— adiciona uma "mensagem flash" à sessão, que estará disponível na próxima página exatamente uma vez. Podemos exibi-la em nosso template Blade.
5. Agrupamento de Rotas
Se você tiver muitas rotas com características comuns (por exemplo, todas elas são para o painel de administração e devem ter o prefixo /admin
e um middleware especial), elas podem ser agrupadas.
<?php
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
// Todas as rotas dentro deste grupo terão:
// 1. Middleware 'auth' e 'admin'
// 2. Prefixo da URL '/admin' (por exemplo, /admin/planets)
// 3. Prefixo do nome 'admin.' (por exemplo, admin.planets.index)
Route::resource('planets', PlanetPageController::class);
// Route::get('/dashboard', ...)->name('dashboard'); // -> admin.dashboard
});
Quiz para Fixação
🚀 Resumo do Capítulo:
Você dominou uma abordagem estruturada e profissional para a organização de rotas web no Laravel. Agora você é capaz de:
- Distinguir as rotas
web
eapi
e seus propósitos. - Usar
Route::resource
para gerar rapidamente rotas CRUD padrão. - Aplicar rotas nomeadas para criar um código flexível e de fácil manutenção.
- Criar operações CRUD completas no controlador com validação e redirecionamentos.
- Agrupar rotas para aplicar regras comuns.
O sistema de navegação da sua "nave" agora é tolerante a falhas e está pronto para expansão. No capítulo final desta seção, combinaremos todo o conhecimento adquirido e exibiremos os dados dos planetas, obtidos via Fetch, em nossa página Blade.