Routes: Fundação da Aplicação
As rotas definem como sua aplicação responde às requisições HTTP. No Laravel, elas são centralizadas no arquivo routes/web.php e funcionam como um mapeamento entre URLs e ações da sua aplicação.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
// Rota simples
Route::get('/', function () {
return view('welcome');
});
// Rota com parâmetro
Route::get('/posts/{id}', [PostController::class, 'show']);
// Rota com validação de parâmetro
Route::get('/users/{id}', [PostController::class, 'user'])->where('id', '[0-9]+');
// Grupo de rotas com prefixo
Route::prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard']);
Route::post('/posts', [AdminController::class, 'store']);
});
// Rotas RESTful automáticas
Route::resource('comments', CommentController::class);
O método resource() é fundamental: gera automaticamente sete rotas padrão (index, create, store, show, edit, update, destroy). Use Route::apiResource() para APIs que não precisam de rotas create e edit. Sempre organize rotas em grupos quando lidam com autenticação ou prefixos comuns.
Controllers: Lógica da Aplicação
Controllers encapsulam a lógica de negócio entre a rota e o banco de dados. Cada método recebe a requisição, processa dados e retorna uma resposta ao usuário.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$posts = Post::paginate(15);
return view('posts.index', ['posts' => $posts]);
}
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string|min:10',
'author_id' => 'required|exists:users,id'
]);
$post = Post::create($validated);
return redirect()->route('posts.show', $post)->with('success', 'Post criado!');
}
public function show(Post $post)
{
return view('posts.show', ['post' => $post]);
}
public function edit(Post $post)
{
return view('posts.edit', ['post' => $post]);
}
public function update(Request $request, Post $post)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string|min:10'
]);
$post->update($validated);
return redirect()->route('posts.show', $post)->with('success', 'Post atualizado!');
}
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('success', 'Post deletado!');
}
}
Observe que usamos Route Model Binding: passar Post $post como parâmetro automaticamente injeta o modelo baseado na URL. Isso elimina a necessidade de Post::find($id). Controllers devem ser enxutos — evite lógica complexa. Use Services ou Repositories para isso.
Request Validation: Proteção de Dados
Validação garante que dados recebidos estão corretos antes de processar. Laravel oferece validação fluente e customizável direto nos controllers.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function authorize()
{
return auth()->check(); // Verifica se usuário está autenticado
}
public function rules()
{
return [
'title' => 'required|string|max:255|unique:posts,title',
'content' => 'required|string|min:10',
'category_id' => 'required|integer|exists:categories,id',
'published_at' => 'nullable|date_format:Y-m-d H:i:s|after_or_equal:today',
'tags' => 'array|max:5',
'tags.*' => 'string|max:50'
];
}
public function messages()
{
return [
'title.required' => 'O título é obrigatório.',
'title.unique' => 'Este título já existe.',
'content.min' => 'O conteúdo deve ter no mínimo 10 caracteres.',
'published_at.after_or_equal' => 'A data não pode ser no passado.'
];
}
public function prepareForValidation()
{
$this->merge([
'slug' => str_slug($this->title)
]);
}
}
Agora no controller, simplifique a validação:
public function store(StorePostRequest $request)
{
$validated = $request->validated(); // Dados já validados
$post = Post::create($validated);
return redirect()->route('posts.show', $post);
}
Use FormRequest quando a validação é complexa ou reutilizável. Regras essenciais: required, email, unique, exists, min, max, confirmed. Para validação inline simples:
$request->validate([
'email' => 'required|email|unique:users,email'
]);
Fluxo Integrado: Exemplo Real
Veja como tudo funciona junto em um caso real de um blog:
Rota (routes/web.php):
Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
Controller (app/Http/Controllers/PostController.php):
public function store(StorePostRequest $request)
{
$post = Post::create($request->validated());
return redirect()->route('posts.show', $post)->with('message', 'Post criado com sucesso!');
}
Form Request (app/Http/Requests/StorePostRequest.php):
Validação acontece automaticamente antes de chegar ao controller. Se falhar, o usuário volta ao formulário com erros.
Blade Template (resources/views/posts/create.blade.php):
<form action="{{ route('posts.store') }}" method="POST">
@csrf
<input type="text" name="title" value="{{ old('title') }}">
@error('title') <span>{{ $message }}</span> @enderror
</form>
Este fluxo garante: segurança (validação antes de tudo), legibilidade (código organizado em camadas) e reutilização (FormRequest em múltiplos controllers).
Conclusão
Domine esses três pilares: Routes definem o mapa da aplicação (use resource() para RESTful), Controllers contêm lógica com Route Model Binding para injeção automática de modelos, e Request Validation protege dados com FormRequests reutilizáveis. Aplicar estas práticas desde o início resulta em código mantível e seguro. Pratique criando um CRUD completo — é o melhor aprendizado.