Tecnologia além do código.
Régys Borges da Silveira
← Voltar para explorar os artigos

Delphi Horse: Simplifique suas APIs com Auto-binding e Validação de DTOs

Neste artigo 10 tópicos

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:

  1. Obter o corpo da requisição (geralmente um JSON).
  2. Instanciar uma classe de domínio ou de transferência de dados (DTO).
  3. Fazer o parse do JSON para a classe manualmente ou via Serializers.
  4. Validar campo por campo (ex: if Nome = '' then Error...).
  5. 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!

Compartilhar por e-mail

0 comentário(s)

Dê-nos sua opinião, seu comentário ajuda o site a crescer e melhorar a qualidade dos artigos.

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.

Um próximo passo para cada interesse.

Continue estudando com os livros, acompanhe as videoaulas ou consulte as soluções para o seu projeto.

Descubra mais sobre Régys Borges da Silveira

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continuar lendo