<h2>Routes: Fundação da Aplicação</h2>
<p>As rotas definem como sua aplicação responde às requisições HTTP. No Laravel, elas são centralizadas no arquivo <code>routes/web.php</code> e funcionam como um mapeamento entre URLs e ações da sua aplicação.</p>
<pre><code class="language-php"><?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);</code></pre>
<p>O método <code>resource()</code> é fundamental: gera automaticamente sete rotas padrão (index, create, store, show, edit, update, destroy). Use <code>Route::apiResource()</code> para APIs que não precisam de rotas create e edit. Sempre organize rotas em grupos quando lidam com autenticação ou prefixos comuns.</p>
<h2>Controllers: Lógica da Aplicação</h2>
<p>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.</p>
<pre><code class="language-php"><?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!');
}
}</code></pre>
<p>Observe que usamos <strong>Route Model Binding</strong>: passar <code>Post $post</code> como parâmetro automaticamente injeta o modelo baseado na URL. Isso elimina a necessidade de <code>Post::find($id)</code>. Controllers devem ser enxutos — evite lógica complexa. Use Services ou Repositories para isso.</p>
<h2>Request Validation: Proteção de Dados</h2>
<p>Validação garante que dados recebidos estão corretos antes de processar. Laravel oferece validação fluente e customizável direto nos controllers.</p>
<pre><code class="language-php"><?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)
]);
}
}</code></pre>
<p>Agora no controller, simplifique a validação:</p>
<pre><code class="language-php">public function store(StorePostRequest $request)
{
$validated = $request->validated(); // Dados já validados
$post = Post::create($validated);
return redirect()->route('posts.show', $post);
}</code></pre>
<p>Use FormRequest quando a validação é complexa ou reutilizável. Regras essenciais: <code>required</code>, <code>email</code>, <code>unique</code>, <code>exists</code>, <code>min</code>, <code>max</code>, <code>confirmed</code>. Para validação inline simples:</p>
<pre><code class="language-php">$request->validate([
'email' => 'required|email|unique:users,email'
]);</code></pre>
<h2>Fluxo Integrado: Exemplo Real</h2>
<p>Veja como tudo funciona junto em um caso real de um blog:</p>
<p><strong>Rota</strong> (<code>routes/web.php</code>):</p>
<pre><code class="language-php">Route::post('/posts', [PostController::class, 'store'])->name('posts.store');</code></pre>
<p><strong>Controller</strong> (<code>app/Http/Controllers/PostController.php</code>):</p>
<pre><code class="language-php">public function store(StorePostRequest $request)
{
$post = Post::create($request->validated());
return redirect()->route('posts.show', $post)->with('message', 'Post criado com sucesso!');
}</code></pre>
<p><strong>Form Request</strong> (<code>app/Http/Requests/StorePostRequest.php</code>):</p>
<p>Validação acontece automaticamente antes de chegar ao controller. Se falhar, o usuário volta ao formulário com erros.</p>
<p><strong>Blade Template</strong> (<code>resources/views/posts/create.blade.php</code>):</p>
<pre><code class="language-blade"><form action="{{ route('posts.store') }}" method="POST">
@csrf
<input type="text" name="title" value="{{ old('title') }}">
@error('title') <span>{{ $message }}</span> @enderror
</form></code></pre>
<p>Este fluxo garante: segurança (validação antes de tudo), legibilidade (código organizado em camadas) e reutilização (FormRequest em múltiplos controllers).</p>
<h2>Conclusão</h2>
<p>Domine esses três pilares: <strong>Routes</strong> definem o mapa da aplicação (use <code>resource()</code> para RESTful), <strong>Controllers</strong> contêm lógica com Route Model Binding para injeção automática de modelos, e <strong>Request Validation</strong> 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.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://laravel.com/docs/11/routing" target="_blank" rel="noopener noreferrer">Laravel Documentation - Routing</a></li>
<li><a href="https://laravel.com/docs/11/controllers" target="_blank" rel="noopener noreferrer">Laravel Documentation - Controllers</a></li>
<li><a href="https://laravel.com/docs/11/validation" target="_blank" rel="noopener noreferrer">Laravel Documentation - Validation</a></li>
<li><a href="https://laravel.com/docs/11/validation#form-request-validation" target="_blank" rel="noopener noreferrer">Laravel Form Requests Best Practices</a></li>
<li><a href="https://laravel.com/docs/11/routing#route-model-binding" target="_blank" rel="noopener noreferrer">Route Model Binding</a></li>
</ul>