PHP

Laravel Routes, Controllers e Request Validation na Prática

8 min de leitura

Laravel Routes, Controllers e Request Validation na Prática

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

<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">&lt;?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PostController;

// Rota simples

Route::get(&#039;/&#039;, function () {

return view(&#039;welcome&#039;);

});

// Rota com parâmetro

Route::get(&#039;/posts/{id}&#039;, [PostController::class, &#039;show&#039;]);

// Rota com validação de parâmetro

Route::get(&#039;/users/{id}&#039;, [PostController::class, &#039;user&#039;])-&gt;where(&#039;id&#039;, &#039;[0-9]+&#039;);

// Grupo de rotas com prefixo

Route::prefix(&#039;admin&#039;)-&gt;group(function () {

Route::get(&#039;/dashboard&#039;, [AdminController::class, &#039;dashboard&#039;]);

Route::post(&#039;/posts&#039;, [AdminController::class, &#039;store&#039;]);

});

// Rotas RESTful automáticas

Route::resource(&#039;comments&#039;, 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">&lt;?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(&#039;posts.index&#039;, [&#039;posts&#039; =&gt; $posts]);

}

public function create()

{

return view(&#039;posts.create&#039;);

}

public function store(Request $request)

{

$validated = $request-&gt;validate([

&#039;title&#039; =&gt; &#039;required | string | max:255&#039;, &#039;content&#039; =&gt; &#039;required|string|min:10&#039;, &#039;author_id&#039; =&gt; &#039;required|exists:users,id&#039;

]);

$post = Post::create($validated);

return redirect()-&gt;route(&#039;posts.show&#039;, $post)-&gt;with(&#039;success&#039;, &#039;Post criado!&#039;);

}

public function show(Post $post)

{

return view(&#039;posts.show&#039;, [&#039;post&#039; =&gt; $post]);

}

public function edit(Post $post)

{

return view(&#039;posts.edit&#039;, [&#039;post&#039; =&gt; $post]);

}

public function update(Request $request, Post $post)

{

$validated = $request-&gt;validate([

&#039;title&#039; =&gt; &#039;required | string | max:255&#039;, &#039;content&#039; =&gt; &#039;required|string|min:10&#039;

]);

$post-&gt;update($validated);

return redirect()-&gt;route(&#039;posts.show&#039;, $post)-&gt;with(&#039;success&#039;, &#039;Post atualizado!&#039;);

}

public function destroy(Post $post)

{

$post-&gt;delete();

return redirect()-&gt;route(&#039;posts.index&#039;)-&gt;with(&#039;success&#039;, &#039;Post deletado!&#039;);

}

}</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">&lt;?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest

{

public function authorize()

{

return auth()-&gt;check(); // Verifica se usuário está autenticado

}

public function rules()

{

return [

&#039;title&#039; =&gt; &#039;required | string | max:255 | unique:posts,title&#039;, &#039;content&#039; =&gt; &#039;required|string|min:10&#039;, &#039;category_id&#039; =&gt; &#039;required|integer|exists:categories,id&#039;, &#039;published_at&#039; =&gt; &#039;nullable|date_format:Y-m-d H:i:s|after_or_equal:today&#039;, &#039;tags&#039; =&gt; &#039;array|max:5&#039;, &#039;tags.*&#039; =&gt; &#039;string|max:50&#039;

];

}

public function messages()

{

return [

&#039;title.required&#039; =&gt; &#039;O título é obrigatório.&#039;,

&#039;title.unique&#039; =&gt; &#039;Este título já existe.&#039;,

&#039;content.min&#039; =&gt; &#039;O conteúdo deve ter no mínimo 10 caracteres.&#039;,

&#039;published_at.after_or_equal&#039; =&gt; &#039;A data não pode ser no passado.&#039;

];

}

public function prepareForValidation()

{

$this-&gt;merge([

&#039;slug&#039; =&gt; str_slug($this-&gt;title)

]);

}

}</code></pre>

<p>Agora no controller, simplifique a validação:</p>

<pre><code class="language-php">public function store(StorePostRequest $request)

{

$validated = $request-&gt;validated(); // Dados já validados

$post = Post::create($validated);

return redirect()-&gt;route(&#039;posts.show&#039;, $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-&gt;validate([

&#039;email&#039; =&gt; &#039;required|email|unique:users,email&#039;

]);</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(&#039;/posts&#039;, [PostController::class, &#039;store&#039;])-&gt;name(&#039;posts.store&#039;);</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-&gt;validated());

return redirect()-&gt;route(&#039;posts.show&#039;, $post)-&gt;with(&#039;message&#039;, &#039;Post criado com sucesso!&#039;);

}</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">&lt;form action=&quot;{{ route(&#039;posts.store&#039;) }}&quot; method=&quot;POST&quot;&gt;

@csrf

&lt;input type=&quot;text&quot; name=&quot;title&quot; value=&quot;{{ old(&#039;title&#039;) }}&quot;&gt;

@error(&#039;title&#039;) &lt;span&gt;{{ $message }}&lt;/span&gt; @enderror

&lt;/form&gt;</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>

Comentários

Mais em PHP

Boas Práticas de Laços de Repetição: for, while, foreach e do-while para Times Ágeis
Boas Práticas de Laços de Repetição: for, while, foreach e do-while para Times Ágeis

Fundamentos dos Laços de Repetição Um laço de repetição é uma estrutura de co...

O que Todo Dev Deve Saber sobre Camada Model: Repositórios e Mapeamento de Dados
O que Todo Dev Deve Saber sobre Camada Model: Repositórios e Mapeamento de Dados

Compreendendo a Camada Model: Fundamentos A camada Model é o coração de qualq...

Guia Completo de Interfaces e Classes Abstratas em PHP
Guia Completo de Interfaces e Classes Abstratas em PHP

Classes Abstratas em PHP Uma classe abstrata é um molde que não pode ser inst...