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.
- Regras de Entidades (invariantes)
- 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.");
}
}
Repare que:
-
ValidarDominio()garante que nenhum objetoRemessainvá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) { }
}
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
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)
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)