DEV Community

Yuri Peixinho
Yuri Peixinho

Posted on • Edited on

Camadas de Validações de um Sistema backend

Introdução

Como você já deve saber, sistemas geralmente têm entrada e saída de dados (Input/Output). Esses dados de entradas são armazenados em alguma base de dados existente. Portanto, esses dados precisam ser controlados e validados para manter a consistência de sua aplicação.

Por exemplo, se temos um campo de CPF (11 dígitos fixos) não podemos deixar o usuário inserir em nossa base de dados um CPF que contém 8 ou 15 dígitos ou que ele consiga criar dois CPFs iguais.

Tipos de validações

No backend existem três níveis principais de validação e é importante entender a diferença entre os conceitos.

  • Validação de Entrada (Camada de API/Controller)
  • Validação de Negócio (Camada de Aplicação /Domain Service)\
  • Validação de Consistência/Infraestrutura

Validação de Entrada (Camadas de API/Controller)

Ocorre logo no início da aplicação (entrada de dados) e o objetivo é garantir que os dados cheguem válidos na camada de aplicação. É nessa camada que será realizado a validação posterior, de negócios. É aqui que o sistema valida a estrutura e o formato, mas nunca a lógica do negócio.

Exemplo: verificar se o CPF tem 11 dígitos, mas não se ele existe no banco.

Validação de Negócio (Camada da Aplicação/Domain Service)

Essa camada é posterior a validação de entrada. Caso todas as informações fornecidas no input da aplicação esteja correta, passamos para a fase da validação de negócio, seu objetivo é garantir que a ação faça sentido pra o sistema.

Existem dois níveis de validação de regra de negócio.

  1. Regras de Entidades (invariantes)
  2. Regras de negócio entre entidades (Serviço de Domínio)

Regras de Entidades (invariantes)

São regras auto-suficientes que pertencem a uma única entidade e vão dentro da própria classe. As invariantes servem pra garantir consistência do domínio.

Exemplos:

  • Não permitir criar um boleto para um cliente bloqueado.
  • Impedir alteração de uma remessa já enviada.
  • Garantir unicidade de um registro lógico (ex: CPF de uma pessoa).
public class Remessa
{
    public Guid RemessaId { get; private set; }
    public int BancoId { get; private set; }
    public Header Header { get; private set; }
    public string ArquivoTXT { get; private set; }

    public Remessa(int bancoId, Header header, string arquivoTXT)
    {
        BancoId = bancoId;
        Header = header;
        ArquivoTXT = arquivoTXT;

        ValidarDominio();
    }

    public void ValidarDominio()
    {
        if (Header is null)
            throw new DomainException("Header da remessa não pode ser nulo.");

        if (string.IsNullOrWhiteSpace(ArquivoTXT))
            throw new DomainException("Arquivo TXT não pode estar vazio.");

        if (Header.Agencia.Length != 4)
            throw new DomainException("A agência deve ter 4 dígitos.");
    }
}

Enter fullscreen mode Exit fullscreen mode

Repare que:

  • ValidarDominio() garante que nenhum objeto Remessa inválido possa existir.
  • O construtor força a validação logo na criação.
  • As propriedades têm private set, ou seja, ninguém de fora pode alterar o estado diretamente.

E você pode criar uma DomainException personalizada (mais elegante do que ValidationException):

public class DomainException : Exception
{
    public DomainException(string message) : base(message) { }
}
Enter fullscreen mode Exit fullscreen mode

Regras de negócios entre Entidades

Essa camada geralmente valida as relações entre entidades, processos e cenário do negócio. Ele é o ponto que entende o contexto e orquestra o uso correto das entidades.

Essa validação não valida formatos ou invariantes. Ele valida cenários de negócios como:

  • “Um cliente não pode ter duas assinaturas ativas”
  • “Não é possível emitir uma fatura para um pedido cancelado”
  • “O banco informado precisa existir e estar ativo”

Percebe que são regras contextuais e relacionais e não estruturais?

Em qua fluxo de processo ela se encaixa? Ela vive entre o application Service e o Domain, e geralmente é acionada logo depois que os dados foram validados e antes de criar ou persistir entidades.

Controller  
    
DTO Validation (FluentValidation) (Validação de formato)
    
Application Service  
    
Business Validation (processo / contexto) <- É aqui que entra!
    
Domain Validation (invariantes da entidade)  
    
Repository / Persistência
Enter fullscreen mode Exit fullscreen mode

Normalmente essa etapa de validação se localiza den tro de Application:

Application/

├── Validation/
   ├── DTO/                # FluentValidation
   ├── Business/           # Regras contextuais
   └── Domain/             # (opcional: regras complexas do domínio)
Enter fullscreen mode Exit fullscreen mode

Essa camada de validação geralmente utiliza repositórios, serviços de domínios e contexto de processos. Isto é:

  • Repositório: verificar estados do sistema (se já exist algo no banco)
  • Serviços de Domínio: se a regra envolve lógica consolidada, por exemplo: verificar limite de crédito, calcular juros, validar estoque
  • Contexto de Processo: estado do sistema e coerência entre entidades, exemplo: impedir fatura de pedido cancelado, proibir duplicidade de remessa.

Validação de Consistência/Infraestrutura

Essa é a última etapa de validação e a mais crucial. O objetivo é proteger o sistema e o banco de dados de inconsistências estruturais. Ocorre na camada de repository e banco de dados.

Exemplos:

  • Chaves únicas (UNIQUE, PRIMARY KEY).
  • Relacionamentos (FOREIGN KEY).
  • Restrições de tipo (CHECK, NOT NULL).

Top comments (0)