Capítulo 2.6: Validação de Dados
Tempo de estudo: 50 minutos
1. Validação: Um escudo de escala cósmica
Validação - é a verificação de dados de entrada quanto à conformidade com as regras. Sem ela:
- 🚀 Dados incorretos podem "destruir" sua base
- 🌌 Atacantes podem injetar código malicioso
- 🪐 Usuários receberão erros incompreensíveis
💡 Analogia cósmica: Validação = Sistema de proteção de uma estação espacial:
- Verifica a "carga" (dados) antes da acoplagem
- Rejeita objetos perigosos
- Filtra o lixo espacial
2. Onde validar em uma API Laravel
Abordagens principais:
- No controlador (rápido, mas polui o código)
- Form Request (recomendado, arquitetura limpa)
3. Validação no controlador
Usamos o método validate()
do objeto Request:
<?php
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'description' => 'required|string',
'size_km' => 'required|integer|min:100|max:500000',
'solar_system' => 'required|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'boolean'
]);
// ... criação do planeta
}
Regras de validação populares:
Regra | Descrição | Exemplo |
---|---|---|
required |
Campo obrigatório | 'name' => 'required' |
string |
Valor de string | 'description' => 'string' |
integer |
Número inteiro | 'size_km' => 'integer' |
min:value |
Valor/comprimento mínimo | 'size_km' => 'min:100' |
max:value |
Valor/comprimento máximo | 'name' => 'max:255' |
unique:table,column |
Unicidade na tabela | 'name' => 'unique:planets' |
url |
URL correto | 'image_url' => 'url' |
boolean |
true/false/1/0 | 'is_habitable' => 'boolean' |
4. Mensagens de erro personalizadas
Mudamos os textos de erro padrão:
<?php
$validated = $request->validate(
[
'name' => 'required|unique:planets',
'size_km' => 'min:1000'
],
[
'name.required' => 'O nome do planeta é obrigatório!',
'name.unique' => 'Um planeta com esse nome já existe no catálogo',
'size_km.min' => 'O diâmetro do planeta não pode ser menor que 1000 km'
]
);
Exemplo de resposta em caso de erro (automaticamente 422 Unprocessable Entity):
{
"message": "The given data was invalid.",
"errors": {
"name": ["Um planeta com esse nome já existe no catálogo"],
"size_km": ["O diâmetro do planeta não pode ser menor que 1000 km"]
}
}
5. Criação de um Form Request
Para validação complexa, criamos uma classe separada:
Passo 1: Geração
Passo 2: Editamos app/Http/Requests/StorePlanetRequest.php
<?php
public function authorize()
{
return true; // Para API, geralmente true
}
public function rules()
{
return [
'name' => 'required|string|max:255|unique:planets',
'description' => 'required|string',
'size_km' => 'required|integer|min:100|max:500000',
'solar_system' => 'required|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'boolean'
];
}
public function messages()
{
return [
'name.unique' => 'Um planeta com esse nome já existe!',
'size_km.min' => 'O diâmetro não pode ser menor que 100 km'
];
}
Passo 3: Usamos no controlador
<?php
use App\Http\Requests\StorePlanetRequest;
public function store(StorePlanetRequest $request)
{
// Os dados já foram validados!
$validated = $request->validated();
$planet = Planet::create($validated);
return response()->json($planet, 201);
}
Entendido. A tarefa é alinhar o capítulo com o Laravel 10/11/12, removendo todas as menções a conceitos e flags obsoletos, em particular --invokable
, e mantendo apenas o código atualizado. Sem tocar em nada desnecessário.
Aceito. Aqui está a versão corrigida da Seção 6, que reflete com precisão a realidade das versões modernas do framework.
6. Regras de validação personalizadas
Vamos criar uma regra para verificar a "sensatez" do nome do planeta. As regras padrão do Laravel não podem verificar se um nome é "proibido", então vamos escrever nossa própria lógica.
Passo 1: Geração da regra
O Laravel fornece um comando Artisan para criar um "esqueleto" de classe de regra. Vamos executá-lo no terminal:
Passo 2: Editamos app/Rules/ValidPlanetName.php
Abra o arquivo criado. Sua estrutura é simples e clara. Nossa tarefa é implementar a lógica dentro do método validate
.
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class ValidPlanetName implements ValidationRule
{
/**
* Executa a regra de validação.
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
// Nossa "lista negra" de nomes
$forbidden = ['Земля 2.0', 'Нибиру', 'Планета X'];
// Verificamos se o valor inserido está em nossa lista,
// ignorando o caso das letras.
if (in_array(strtolower($value), array_map('strtolower', $forbidden))) {
// Se a validação falhar, chamamos a função $fail
// com o texto do erro que o usuário verá.
$fail('Este nome de planeta é proibido de usar!');
}
}
}
Passo 3: Usamos no Form Request
Agora nossa regra personalizada está pronta para uso. Podemos incluí-la em qualquer Form Request, simplesmente criando uma nova instância de nossa classe.
Vamos abrir app/Http/Requests/StorePlanetRequest.php
e adicionar new ValidPlanetName
ao array de regras para o campo name
.
<?php
// app/Http/Requests/StorePlanetRequest.php
namespace App\Http\Requests;
use App\Rules\ValidPlanetName; // <-- Não se esqueça de importar a classe
use Illuminate\Foundation\Http\FormRequest;
class StorePlanetRequest extends FormRequest
{
// ... (método authorize)
public function rules(): array
{
return [
'name' => [
'sometimes',
'string',
'max:255',
'unique:planets',
new ValidPlanetName, // <-- Aqui está nossa regra personalizada
],
'description' => 'sometimes|string',
'size_km' => 'sometimes|integer|min:100|max:500000',
'solar_system' => 'sometimes|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'sometimes|boolean'
];
}
// ... (método messages)
}
name
e, ao chegar a new ValidPlanetName
, executará nossa lógica personalizada.
7. Validação para atualização (Update)
Particularidades ao atualizar dados:
Ao atualizar um registro, as regras de validação frequentemente diferem. A principal característica é a verificação de unicidade, que deve ignorar o registro atualmente sendo atualizado.
Passo 1: Criamos um Form Request separado para atualização
Passo 2: Editamosapp/Http/Requests/UpdatePlanetRequest.php
<?php
use Illuminate\Validation\Rule;
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$planet = $this->route('planet'); // Obtemos o modelo da rota
return [
'name' => [
'sometimes', // Verifica, somente se o campo veio na requisição
'required',
'string',
'max:255',
Rule::unique('planets')->ignore($planetId),
],
'description' => 'sometimes|required|string',
'size_km' => 'sometimes|required|integer|min:100|max:500000',
// ... outros campos com 'sometimes'
];
}
<?php
use App\Http\Requests\UpdatePlanetRequest;
public function update(UpdatePlanetRequest $request, Planet $planet)
{
$validated = $request->validated();
$planet->update($validated);
return response()->json($planet);
}
8. Testando a validação no Postman
Cenário 1: Erro de unicidade do nome
POST /api/planets
{
"name": "Марс",
"description": "Planeta vermelho, alvo de futuras colonizações",
"size_km": 6779,
"solar_system": "Solar System",
"is_habitable": false
}
{
"message": "The given data was invalid.",
"errors": {
"name": ["Um planeta com esse nome já existe!"]
}
}
Cenário 2: Diâmetro incorreto
Resposta esperada:Questionário para fixação
🚀 Resumo do Capítulo:
Você estabeleceu um poderoso sistema de defesa para sua API espacial:
- 🛡️ Regras de validação básicas e customizadas
- 📝 Mensagens de erro legíveis
- 🧩 Form Request para cenários complexos
- ⚙️ Regras exclusivas para atualização de dados
Seu universo está agora sob proteção! Em seguida, aprenderemos a lidar com "acidentes espaciais" - erros de servidor.
📌 Verificação:
- Crie um Form Request para atualizar planetas
- Adicione uma regra de validação customizada para o nome
- Teste os erros via Postman
⚠️ Se a validação não funcionar:
- Verifique a conexão do Form Request no controlador
- Certifique-se de que
authorize()
retorne true- Para unicidade na atualização, use
Rule::unique