Laravel Routes, Controllers e Request Validation na Prática Já leu

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 e funcionam como um mapeamento entre URLs e ações da sua aplicação. O método é fundamental: gera automaticamente sete rotas padrão (index, create, store, show, edit, update, destroy). Use 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. Observe que usamos Route Model Binding: passar como parâmetro automaticamente injeta o modelo baseado na URL. Isso elimina a necessidade de . 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

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.

Referências


Artigos relacionados