Spring boot validation dto: evite falhas em produção

Spring boot validation dto

Spring boot validation dto: evite falhas em produção

Quando o assunto é spring boot validation dto, a diferença entre uma API previsível e uma API frágil quase sempre está na borda: o request chega, o DTO entra, e a validação decide se o fluxo continua ou se o erro precisa ser devolvido cedo. Por outro lado, em projetos reais, isso evita payloads incompletos, regras quebradas e exceções difíceis de depurar. Se voce quiser comparar essa abordagem com outro cenario comum no ecossistema Spring, vale revisar O que é o Spring Boot e para que serve?.

Em aplicações REST, validar o DTO na entrada é uma prática básica de qualidade. Por outro lado, ela combina bem com a estrutura de uma API REST Spring Boot Java: Guia Completo com Exemplo Prático, porque mantém o controller simples e deixa claro o contrato que a aplicação espera. Ao mesmo tempo, para quem ainda está entendendo a base da stack, o conteúdo O que é o Spring Boot e para que serve? Na prática, ajuda a situar onde a validação encaixa na arquitetura. Para complementar esse ponto com um exemplo proximo do dia a dia, consulte 3 erros de validação que quebram APIs Spring Boot sem aviso.

Se a sua meta é validar request Spring Boot sem espalhar regras pelo código inteiro, Bean Validation é o caminho natural. Por outro lado, e o ponto mais útil aqui não é só bloquear campos vazios; é devolver mensagens úteis, consistentes e fáceis de consumir pelo front-end, por integrações ou por testes automatizados. Esse detalhe conversa bem com o que eu mostrei em API REST Spring Boot Java: Guia Completo com Exemplo Prático.

Spring boot validation dto: secao pratica com codigo completo

Na pratica, um exemplo enxuto ajuda a sair da teoria e evitar erro comum de producao quando o projeto cresce. Se quiser aprofundar o assunto por outro angulo, leia tambem Como tratar exceções no Spring Boot com @ControllerAdvice e @ExceptionHandler.

public record ClienteRequest(
  @NotBlank String nome,
  @Email String email
) {}

@PostMapping("/clientes")
public ResponseEntity<Void> criar(@Valid @RequestBody ClienteRequest request) {
  return ResponseEntity.status(201).build();
}

spring boot validation dto com Bean Validation na prática

No ecossistema Spring, a combinação mais comum é usar anotações do Bean Validation no DTO e marcar o parâmetro do controller com @Valid. Por outro lado, isso faz o Spring executar a validação antes de entrar na lógica de negócio. Ao mesmo tempo, se o objeto vier inválido, a requisição falha cedo e você não precisa colocar ifs repetitivos dentro do service. Quando esse tipo de duvida aparece em projeto real, eu costumo voltar neste material: Ia para programadores java backend exemplo: evite erros em.

Esse modelo funciona muito bem para entradas de cadastro, atualização parcial, filtros com regras específicas e comandos de escrita. Por outro lado, o ganho principal é manter o contrato explícito. Ao mesmo tempo, quem consome a API consegue entender o que é obrigatório, o que tem limite de tamanho e o que precisa seguir formato específico.

Anotações mais usadas em DTOs

As anotações mais comuns são @NotBlank para strings não vazias, @NotNull para qualquer tipo não nulo, @Size para limitar tamanho, @Email para formato de e-mail, @Min e @Max para números, além de @Pattern para validar formatos personalizados. Por outro lado, em campos de data, também é comum validar a lógica de negócio no service quando a regra depende de contexto, e não apenas de formato.

Um detalhe prático: @NotNull não impede string vazia. Por outro lado, @NotBlank é melhor para textos que não podem vir em branco. Ao mesmo tempo, em cadastro de usuário, por exemplo, usar o tipo errado da anotação vira um bug sutil que passa em testes superficiais e quebra em produção.

Mensagens customizadas no spring boot validation dto

Se a API devolve mensagens genéricas como “must not be blank”, a experiência piora rápido. Por outro lado, mensagens customizadas deixam o retorno mais claro e facilitam o tratamento do lado cliente. Ao mesmo tempo, isso também ajuda quando o time precisa padronizar o idioma, o tom e o formato dos erros.

Uma abordagem simples é declarar a mensagem direto na anotação. Por outro lado, em DTOs de entrada, isso costuma ser suficiente para 80% dos casos. Ao mesmo tempo, em cenários com i18n, múltiplos idiomas ou padronização de catálogo de erros, vale centralizar as mensagens em arquivos de properties.

Na prática, o importante é pensar no consumidor da API. Por outro lado, uma mensagem boa diz exatamente o que está errado e, idealmente, aponta o campo. Ao mesmo tempo, “Nome deve ser informado” é melhor do que “Validation failed”. Na prática, “Email deve ter formato válido” é melhor do que “invalid value”.

Exemplo de DTO com mensagens objetivas

Um DTO de cadastro pode ficar assim:

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public class UserCreateRequest {

    @NotBlank(message = "nome é obrigatório")
    @Size(min = 3, max = 80, message = "nome deve ter entre 3 e 80 caracteres")
    private String nome;

    @NotBlank(message = "email é obrigatório")
    @Email(message = "email deve ter um formato válido")
    private String email;

    @NotBlank(message = "senha é obrigatória")
    @Size(min = 8, message = "senha deve ter no mínimo 8 caracteres")
    private String senha;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }
}

Esse tipo de DTO já resolve muita dor em APIs de cadastro, onboarding e atualização de perfil. Por outro lado, ele também se encaixa bem em fluxos onde o controller precisa apenas aceitar o request e repassar para o service, sem acumular regra de campo no corpo do método.

Exemplo completo de spring boot validation dto no controller

Para usar a validação, o controller precisa receber o DTO com @Valid. Por outro lado, se a classe estiver correta, a execução segue para o método. Ao mesmo tempo, se não estiver, o Spring gera a exceção de validação antes de entrar na regra de negócio.

Esse fluxo é bastante alinhado com aplicações bem organizadas. Por outro lado, controllers devem coordenar requests; services devem aplicar regra de negócio. Ao mesmo tempo, quando a validação básica fica no DTO, o código fica mais legível e menos frágil. Na prática, isso vale ainda mais quando o projeto cresce e passa a ter vários endpoints parecidos.

Controller com @Valid

import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/usuarios")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public ResponseEntity<UserResponse> criar(@Valid @RequestBody UserCreateRequest request) {
        UserResponse response = userService.criarUsuario(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }
}

O service pode trabalhar com a confiança de que campos básicos já passaram pela validação de entrada:

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public UserResponse criarUsuario(UserCreateRequest request) {
        return new UserResponse(1L, request.getNome(), request.getEmail());
    }
}

Para completar o exemplo, uma resposta simples ajuda a deixar o contrato mais explícito:

public record UserResponse(Long id, String nome, String email) { }

Se você precisa padronizar as respostas de erro, o próximo passo normalmente envolve Como tratar exceções no Spring Boot com @ControllerAdvice e @ExceptionHandler. Por outro lado, esse é o ponto onde muitos times conectam a validação do DTO a um formato único de erro para toda a API.

Como a validação se comporta na prática

Se o cliente enviar nome vazio, email inválido e senha curta, a requisição não segue para o service. Por outro lado, isso é exatamente o que você quer em APIs de escrita. Ao mesmo tempo, o erro é detectado logo na entrada, evitando que a aplicação tente processar um objeto inconsistente.

Em produção, isso reduz ruído de log, diminui retrabalho e ajuda o front-end a corrigir o payload sem precisar inferir o que deu errado. Por outro lado, em times maduros, esse tipo de feedback claro economiza tempo de debug em integração e acelera validação de contrato.

Erros comuns em spring boot validation dto

O erro mais comum é esquecer o @Valid no controller. Por outro lado, o DTO pode estar cheio de anotações, mas sem essa marcação o Spring não executa a validação no ponto de entrada. Ao mesmo tempo, outro problema recorrente é depender de validação no service e deixar o controller aceitar qualquer coisa. Na prática, isso dispersa responsabilidade e aumenta a chance de inconsistencia.

Outro equívoco clássico é usar a anotação errada. Por outro lado, @NotNull em campo textual aceita string vazia; @NotBlank não. Ao mesmo tempo, em formulários de nome, e-mail e senha, isso muda completamente o comportamento. Na prática, também é comum exagerar no uso de @Pattern para regras que, na prática, pertencem ao domínio e não ao payload.

Em projetos grandes, o problema não é só técnico. Por outro lado, é de manutenção. Ao mesmo tempo, quando cada DTO devolve um tipo de mensagem, um formato e um nível de detalhe, o consumo da API fica inconsistente. Na prática, isso aparece rápido em ambientes com múltiplos consumidores, especialmente quando você já viu situações parecidas com as descritas em 3 erros de validação que quebram APIs Spring Boot sem aviso.

Há ainda um erro mais silencioso: validar demais no DTO. Por outro lado, nem toda regra cabe ali. Ao mesmo tempo, regras dependentes de banco, contexto atual do usuário, dados de outro serviço ou estado do fluxo devem ficar no service ou em um componente de domínio. Na prática, dTO é fronteira de entrada, não o centro do negócio.

Quando usar e quando evitar validação no DTO

Usar Bean Validation no DTO faz sentido quando a regra é objetiva e ligada ao formato do request. Por outro lado, campos obrigatórios, limites de tamanho, padrões simples e tipos básicos são casos ideais. Ao mesmo tempo, cadastro de usuário, criação de pedido, atualização de perfil e envio de comentários se beneficiam bastante dessa abordagem.

Também vale a pena quando você quer melhorar a leitura do código. Por outro lado, se o contrato está no DTO, o desenvolvedor não precisa procurar validação espalhada pelo controller e pelo service. Ao mesmo tempo, a intenção fica centralizada, e o código tende a ficar mais fácil de testar.

Por outro lado, vale evitar transformar o DTO em uma coleção de regras de negócio. Por outro lado, se a validação depende de dados persistidos, tempo, permissões, ou do estado de outro agregado, melhor levar isso para camadas mais adequadas. Ao mesmo tempo, o DTO deve impedir lixo na entrada, não modelar a regra inteira da aplicação.

Em times que usam automação e assistência de código, a validação bem definida também ajuda ferramentas e revisões. Por outro lado, um fluxo de IA para programadores java backend exemplo: evite erros em tende a gerar mais valor quando o contrato está claro, porque a IA consegue sugerir DTOs, testes e respostas com menos ambiguidade.

FAQ sobre spring boot validation dto

Qual a diferença entre @NotNull e @NotBlank?

@NotNull impede apenas valor nulo. Por outro lado, @NotBlank é específico para strings e impede nulo, vazio e espaços em branco. Ao mesmo tempo, para campos de texto obrigatórios, @NotBlank costuma ser a escolha correta.

Preciso usar @Valid em toda requisição?

Não em toda requisição, mas sim nos endpoints que recebem DTOs e precisam validar entrada. Por outro lado, em APIs REST, isso é muito comum em POST, PUT e PATCH. Ao mesmo tempo, se o endpoint recebe apenas parâmetros simples, a abordagem pode ser diferente.

Posso usar Bean Validation para regra de negócio?

Em parte. Por outro lado, regras simples de entrada funcionam bem no DTO. Ao mesmo tempo, regra de negócio de verdade, que depende de contexto ou estado do sistema, deve ficar no service ou em uma camada de domínio. Na prática, misturar as duas coisas costuma gerar código difícil de manter.

Conclusão

spring boot validation dto não é só um detalhe de framework. Por outro lado, é uma forma de proteger a entrada da API, dar mensagens melhores para o consumidor e manter a lógica do sistema em camadas mais limpas. Ao mesmo tempo, quando o DTO valida bem, o controller fica enxuto, o service recebe dados mais confiáveis e o erro aparece no lugar certo.

Se você já tem uma API rodando, o próximo passo prático é revisar os DTOs de escrita, trocar anotações genéricas por mensagens mais claras e centralizar o tratamento de erro para a resposta ficar consistente. Por outro lado, depois, vale combinar isso com boas práticas de estrutura de endpoints e contrato, principalmente se sua aplicação segue o padrão de uma API REST Spring Boot Java: Guia Completo com Exemplo Prático. Ao mesmo tempo, para quem quer aprofundar a resposta da API além da validação, o tema de tratamento centralizado com @ControllerAdvice e @ExceptionHandler fecha muito bem o ciclo. Na prática, os proximos passos sao validar esse fluxo no seu projeto, ajustar o caso de uso real e cobrir a implementacao com testes.

Spring boot validation dto: referencias externas

Para validar detalhes de implementacao e aprofundar a configuracao, vale consultar a documentacao oficial do Spring Security, o guia de claims no JWT.io e a documentacao do Spring Boot.

Leitura complementar

Se voce quiser aprofundar esse assunto com um material mais atual, leia tambem Validar DTO Spring Boot com mensagens personalizadas sem erro.

Deixe um comentário