Quem desenvolve APIs em Delphi utilizando o framework Horse sabe o quanto ele é leve, rápido e extremamente eficiente. No entanto, à medida que a aplicação cresce, começamos a nos deparar com um problema comum em nossos controllers: o excesso de código repetitivo (o famoso boilerplate) para ler payloads de requisições e validar os dados de entrada.
Se você se cansa de escrever dezenas de linhas checando se campos obrigatórios foram preenchidos, se e-mails são válidos ou se um valor numérico está no intervalo correto, você precisa conhecer o horse-dto.
Neste artigo, vamos entender como esse middleware automatiza o processo de desserialização e validação declarativa de dados usando atributos no Delphi.
O Problema: O Excesso de Boilerplate nos Controllers
Tipicamente, ao criar um endpoint de cadastro, seu controller precisa realizar os seguintes passos:
- Obter o corpo da requisição (geralmente um JSON).
- Instanciar uma classe de domínio ou de transferência de dados (DTO).
- Fazer o parse do JSON para a classe manualmente ou via Serializers.
- Validar campo por campo (ex:
if Nome = '' then Error...). - Liberar a memória em blocos
try..finally.
Essa abordagem polui o controller, violando o princípio de Responsabilidade Única (SRP) do SOLID, já que seu controller acaba fazendo mais do que simplesmente orquestrar a requisição e a resposta.
A Solução: Horse DTO & Validation Middleware
O horse-dto é uma biblioteca que introduz o conceito de validação declarativa baseada em atributos e auto-binding (vinculação automática de dados). Com ele, você define as regras de validação diretamente na sua classe DTO através de atributos e deixa que o middleware faça toda a desserialização e consistência dos dados de forma automática.
Passo a Passo Prático de Implementação
1. Instalação
Adicionar a dependência ao seu projeto Delphi é extremamente simples utilizando o gerenciador de pacotes Boss. No terminal da pasta do seu projeto, execute:
boss install horse-dto
2. Declarando o DTO com Atributos de Validação
Em vez de validar seus dados programaticamente, você passa a decorá-los de forma elegante. Veja o exemplo de um DTO de cadastro de usuário:
unit DTO.Usuario;
interface
uses
Horse.DTO;
type
TUsuarioCadastroDTO = class
private
FNome: string;
FEmail: string;
FIdade: Integer;
public
[Required('O nome é obrigatório')]
[MinLength(3, 'O nome deve ter no mínimo 3 caracteres')]
property Nome: string read FNome write FNome;
[Required('O e-mail é obrigatório')]
[Email('E-mail em formato inválido')]
property Email: string read FEmail write FEmail;
[Range(18, 120, 'O usuário deve ter entre 18 e 120 anos')]
property Idade: Integer read FIdade write FIdade;
end;
implementation
end.
3. Registrando o Middleware na Rota
Agora, basta informar ao Horse que você deseja utilizar o middleware genérico THorseDTO<T>.AsMiddleware() ao registrar a rota. O middleware intercepta a requisição, valida os dados e injeta o objeto já preenchido diretamente no corpo da requisição:
uses
Horse,
Horse.DTO,
DTO.Usuario;
procedure CadastrarUsuario(Req: THorseRequest; Res: THorseResponse);
var
LInput: TUsuarioCadastroDTO;
begin
// O objeto já vem validado e instanciado pelo middleware!
LInput := Req.Body<TUsuarioCadastroDTO>;
// Processe seus dados com total segurança.
// Observação: O ciclo de vida da memória do objeto é controlado automaticamente pelo middleware!
Res.Send('Usuário ' + LInput.Nome + ' cadastrado com sucesso!');
end;
begin
// Registra o middleware na rota POST
THorse.Post('/usuarios', [THorseDTO<TUsuarioCadastroDTO>.AsMiddleware()], CadastrarUsuario);
THorse.Listen(9000);
end.
Como o Middleware trata as inconsistências?
Se o cliente da sua API enviar dados inconsistentes, como uma idade abaixo de 18 anos ou um e-mail mal formatado, o middleware interrompe o fluxo imediatamente. Ele responde automaticamente ao cliente com o código HTTP 400 Bad Request e envia um JSON estruturado com a lista de erros:
{
"error": "Erro de validação de DTO",
"errors": [
{
"field": "Email",
"message": "E-mail em formato inválido"
},
{
"field": "Idade",
"message": "O usuário deve ter entre 18 e 120 anos"
}
]
}
Isso garante que seu controller só receba dados 100% íntegros e reduz dezenas de tratativas manuais de erro.
Atributos de Validação Prontos para Uso
O pacote traz diversos atributos integrados de fábrica para facilitar seu desenvolvimento diário:
- [Required]: Garante que a propriedade foi enviada e não está vazia.
- [MinLength] e [MaxLength]: Controlam o limite de caracteres para strings.
- [Range]: Define limites numéricos mínimos e máximos (para Integers e Floats).
- [Email]: Valida se o formato do e-mail é legítimo via RegEx.
- [Pattern]: Permite que você informe uma Expressão Regular customizada para validação.
- [CustomValidator]: Para validações complexas e regras de negócio personalizadas.
Estendendo com Validações Personalizadas (Custom Validator)
Há casos em que precisamos ir além do formato e checar regras de negócio complexas, como validar um CPF/CNPJ ou verificar no banco de dados se um registro é duplicado. Para fazer isso, basta implementar a interface IHorseDTOValidator:
type
TValidadorCPF = class(TInterfacedObject, IHorseDTOValidator)
public
function Validate(const AValue: TValue; out AErrorMessage: string): Boolean;
end;
function TValidadorCPF.Validate(const AValue: TValue; out AErrorMessage: string): Boolean;
begin
Result := ValidarCPF(AValue.AsString); // Sua função interna de validação de CPF
if not Result then
AErrorMessage := 'CPF informado é inválido';
end;
Em seguida, basta aplicar o atributo na propriedade correspondente do DTO:
[CustomValidator(TValidadorCPF)]
property CPF: string read FCPF write FCPF;
Conclusão
Adotar o horse-dto é uma excelente decisão de arquitetura para quem busca construir APIs profissionais, limpas e escaláveis em Delphi. Ao desacoplar a lógica de validação de entrada de dados dos controllers, você ganha legibilidade, facilita a manutenção de testes e acelera a entrega de novos recursos.
Você já utiliza validação declarativa nas suas APIs Delphi? Deixe sua opinião nos comentários!
Descubra mais sobre Régys Borges da Silveira
Assine para receber nossas notícias mais recentes por e-mail.
Dê-nos sua opinião, seu comentário ajuda o site a crescer e melhorar a qualidade dos artigos.