Skip to content

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:

  1. No controlador (rápido, mas polui o código)
  2. 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

php artisan make:request StorePlanetRequest

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:

php artisan make:rule ValidPlanetName

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)
}
Pronto. Agora, ao criar um planeta, o Laravel aplicará sequencialmente todas as regras ao campo 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

php artisan make:request UpdatePlanetRequest
Passo 2: Editamos app/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'
     ];
 }
Passo 3: Usamos no controlador
<?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
}
Resposta esperada:
{
    "message": "The given data was invalid.",
    "errors": {
        "name": ["Um planeta com esse nome já existe!"]
    }
}

Cenário 2: Diâmetro incorreto

{
    "name": "Planeta-Ervilha",
    "size_km": 50 // < min:100
}
Resposta esperada:
"errors": {
    "size_km": ["O diâmetro não pode ser menor que 100 km"]
}


Questionário para fixação

1. Status HTTP em caso de erros de validação:

2. Regra para verificação de unicidade:

3. Onde é melhor colocar regras de validação complexas?

4. O método `authorize()` no Form Request deve retornar:

5. A regra sometimes significa:


🚀 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:

  1. Crie um Form Request para atualizar planetas
  2. Adicione uma regra de validação customizada para o nome
  3. 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