O Rest Client Moderno que o Delphi Merecia: Conheça o Dext Rest Client

O Delphi sempre foi sinônimo de produtividade. No entanto, à medida que nossas aplicações evoluem para arquiteturas distribuídas e microsserviços, a forma como consumimos APIs precisa acompanhar essa modernidade.
Muitas vezes, a abordagem tradicional baseada em componentes visuais (TRestClient), embora excelente para prototipagem, pode adicionar complexidade desnecessária e verbosidade ao código de produção, especialmente quando lidamos com requisições dinâmicas, autenticação complexa e concorrência.
No desenvolvimento do Dext Framework, buscamos uma experiência de desenvolvimento que unisse a performance nativa do Delphi com a elegância das APIs fluentes modernas.
O resultado é o Dext.Net.RestClient. E ele vai mudar a forma como você consome APIs no Delphi.
1. O Fim do “Component-Hell”
Seção intitulada “1. O Fim do “Component-Hell””O Dext Rest Client adota uma abordagem Code-First. Esqueça os componentes visuais. O código deve contar a história completa da requisição.
Como fazíamos (Modo Tradicional):
- Arrasta componente
TRestClient1 - Arrasta
TRestRequest1(e liga no client) - Arrasta
TRestResponse1(e liga no request) - No código:
RestRequest1.Params.AddItem('Authorization', 'Bearer ' + Token, pkHTTPHEADER); RestRequest1.Execute;
Como fazemos com Dext (Modo Fluente):
uses Dext.Net.RestClient; // A única unit que você precisa
var Users: TList<TUser>;begin Users := RestClient('https://api.exemplo.com') .BearerToken(MyJwtToken) .Timeout(5000) .Get<TList<TUser>>('/users?role=admin') // Serialização automática de Listas! .Await; // Síncrono ou Assíncrono, você escolheend;É limpo, legível e, o mais importante, seguro em tempo de compilação. Se você mudar o tipo de retorno, o compilador te avisa.
2. Performance: O Poder do Connection Pooling
Seção intitulada “2. Performance: O Poder do Connection Pooling”Aqui está o segredo que torna o Dext muito mais rápido que a implementação padrão para cenários de alta carga.
Criar uma instância de TNetHttpClient é caro (Handles de OS, SSL Handshake, etc). Se você cria e destrói um Client para cada requisição em um loop, sua performance sofre.
O TRestClient do Dext é, na verdade, um Record leve que atua como fachada para um Connection Pool Thread-Safe.
- Quando você faz uma requisição, pegamos um
THttpClient“quente” (já criado) do pool. - Executamos a requisição.
- Devolvemos ao pool imediatamente.
Isso permite escalar sua aplicação para lidar com alta concorrência de forma eficiente, reutilizando recursos de conexões TCP/SSL custosos. E sim, é 100% Thread-Safe por design.
3. Arquitetura Assíncrona e “Delphi Threads”
Seção intitulada “3. Arquitetura Assíncrona e “Delphi Threads””O Dext não depende de chamadas manuais como ProcessMessages (que podem gerar efeitos colaterais de reentrância) para manter a UI responsiva. Ele é construído sobre a biblioteca Dext.Threading, utilizando um pool de threads inteligente (Work Stealing).
O Gancho do Cancellation Token
Seção intitulada “O Gancho do Cancellation Token”Em meu livro, “Delphi Multithreading”, dedico tópico inteiro a explicar por que cancelar uma tarefa é tão vital quanto executá-la.
Imagine um “Auto-Complete”. O usuário digita “D”, “e”, “l”… você não quer 3 requisições concorrendo. Você quer cancelar a anterior assim que a próxima chega.
Com Dext, isso é trivial:
procedure TFormSearch.EditChange(Sender: TObject);begin // Cancela a busca anterior automaticamente CancellationTokenSource.Cancel; CancellationTokenSource := TCancellationTokenSource.Create;
RestClient.Get<TSearchResult>('/search') .QueryParam('q', EditSearch.Text) .Cancellation(CancellationTokenSource.Token) // Integração nativa .OnComplete(procedure(Res: TSearchResult) begin // Atualiza Grid na Thread Principal automaticamente Grid.DataSource := Res.Verify; end) .Start;end;Pipelines e Encadeamento (Chaining)
Seção intitulada “Pipelines e Encadeamento (Chaining)”E se você precisar autenticar antes de buscar dados? Em vez de aninhar callbacks (“Callback Hell”), você pode encadear operações de forma linear usando o método .ThenBy.
O Dext.Net.RestClient se integra perfeitamente ao Dext.Threading.Async, permitindo que o resultado de uma requisição alimente a próxima:
RestClient.Get<TToken>('/auth/token') .ThenBy<TUser>( function(Token: TToken): TUser begin // Este bloco roda automaticamente após o sucesso da primeira requisição. // E dentro dele, podemos fazer outra chamada síncrona (Await) sem travar a UI! Result := RestClient.Get('/profile') .Header('Authorization', Token.AccessToken) .Execute<TUser> .Await; end) .OnComplete(procedure(User: TUser) begin // Só chega aqui quando TUDO terminar com sucesso UserProfile.Text := User.Name; end) .Start;Isso transforma fluxos complexos em código plano e fácil de ler.
4. Inovação: Arquivos .http (O Padrão de Mercado)
Seção intitulada “4. Inovação: Arquivos .http (O Padrão de Mercado)”Esta é a killer feature para produtividade.
O Dext traz suporte nativo a arquivos .http (padrão usado pelo VS Code e IntelliJ). Você pode documentar e testar suas APIs em arquivos texto simples dentro do seu projeto:
@baseUrl = https://api.production.com@authToken = eyJhbGciOiJIUzI1Ni...
### Criar Novo PedidoPOST {{baseUrl}}/ordersAuthorization: Bearer {{authToken}}Content-Type: application/json
{ "productId": 1050, "qty": 5}Sintaxe simples e poderosa: Variáveis com @, separador de requisições com ###.
E no seu código Delphi, você executa isso diretamente:
uses Dext.Http.Parser;
var Requests: THttpRequestCollection; Req: THttpRequestInfo;begin // 1. Carrega o arquivo Requests := THttpRequestParser.ParseFile('orders.http'); try // 2. Busca a requisição pelo nome Req := Requests.FindByName('Criar Novo Pedido');
// 3. Resolve variáveis (interpolando {{baseUrl}}) THttpRequestParser.ResolveRequest(Req, Requests.Variables);
// 4. Executa RestClient.Execute(Req).Await; finally Requests.Free; end;end;5. Dext Dashboard: Seu “Postman” Nativo
Seção intitulada “5. Dext Dashboard: Seu “Postman” Nativo”Nós integramos esse suporte no Dext Dashboard. Veja isso:
Chega de manter Collections desatualizadas em ferramentas externas.
Com o Dext Dashboard, você executa os próprios arquivos .http do seu projeto. É a mesma “fonte da verdade” para o código, para os testes e para o desenvolvedor.
- Edição com Syntax Highlighting: Escreva seus
.httpcom conforto. - Execução Real: O Dashboard roda a requisição usando o mesmo motor
Dext.Net.RestClientda sua aplicação. O que você vê é exatamente o que seu código vai receber. - Histórico e Logs: Analise tempo de resposta, headers e payload JSON formatado.
Isso mantém você no “Flow State”. Código, Teste, Documentação… tudo no mesmo lugar.
6. Testabilidade: O Pesadelo dos DataModules Acabou
Seção intitulada “6. Testabilidade: O Pesadelo dos DataModules Acabou”Qualquer desenvolvedor que já tentou criar testes unitários para um formulário ou DataModule acoplado a componentes TRestClient sabe a dor que é. Você precisa instanciar o formulário, garantir que a IDE não crie conexões automáticas, e é quase impossível “fingir” (mock) uma resposta do servidor sem subir um servidor HTTP local.
O Dext.Net.RestClient foi desenhado pensando em TDD (Test Driven Development).
A arquitetura baseada em interfaces (IRestClient) permite que você injete mocks facilmente usando o Dext.Mocks e valide resultados com o Dext.Testing, sem depender de bibliotecas externas.
Exemplo de Teste de Regra de Negócio (Isolado da Rede):
uses Dext.Mocks, Dext.Assertions;
procedure TFreightServiceTest.DeveTratarErroDeAPI;var MockClient: Mock<IHttpClient>; // Interface abstraída Service: TFreightService;begin // Configura o Mock MockClient := Mock<IHttpClient>.Create;
// Define comportamento: Quando chamar 'Calculate', retorna erro 503 MockClient.Setup.Returns(503).When.Calculate(Arg.Any<string>);
// Injeta o mock (nada de rede real!) Service := TFreightService.Create(MockClient.Instance);
// Valida comportamento com Fluent Assertions // Se a API falha, o serviço deve retornar 0.0 (regra de negócio) Should(Service.CalculateFreight('12345-678')).Be(0.0);end;Essa capacidade de desacoplar sua lógica de negócio da infraestrutura de rede é o que diferencia aplicações profissionais de códigos legados difíceis de manter.
7. O Ciclo Completo: Testes de Integração com Controllers
Seção intitulada “7. O Ciclo Completo: Testes de Integração com Controllers”Vamos elevar o nível. Imagine testar seu servidor HTTP Dext (Controller) usando o próprio Dext Rest Client e arquivos .http como massa de testes.
Considere este Controller de Pedidos:
type [DextController('/api/orders')] TOrdersController = class(TController) private FService: IOrderService; public constructor Create(AService: IOrderService);
[DextPost] function CreateOrder([Body] Order: TOrderDTO): IActionResult; end;Podemos escrever um Teste de Integração que sobe o servidor em memória, injeta um Service Mockado no Controller, e usa os arquivos .http para validar a resposta.
Primeiro, o arquivo de cenário scenarios/create-order.http:
### Criar Novo PedidoPOST /api/ordersContent-Type: application/json
{ "productId": 1050, "qty": 5}Agora, o teste que executa esse cenário contra o servidor em memória:
procedure TIntegrationTest.TestCreateOrderFlow;var Server: TDextApplication; MockService: Mock<IOrderService>; Response: IRestResponse; RequestInfo: THttpRequestInfo; Requests: THttpRequestCollection;begin // 1. Configura o Mock do Service (Backend) MockService := Mock<IOrderService>.Create; MockService.Setup.Returns(True).When.ProcessOrder(Arg.Any<TOrder>);
// 2. Sobe o Servidor em Memória injetando o Mock // DextApplication pode ser instanciada leve para testes Server := TDextApplication.Create; Server.Services.AddSingleton<IOrderService>(MockService.Instance); Server.Start(8090); // Porta aleatória/dedicada para teste
try // 3. Carrega o arquivo .http // Dext tem um parser nativo para este formato Requests := THttpRequestParser.ParseFile('scenarios/create-order.http'); try // Obtém a requisição pelo nome definido (### Criar Novo Pedido) RequestInfo := Requests.FindByName('Criar Novo Pedido');
// Resolve variáveis (URL do servidor de teste) RequestInfo.Url := 'http://localhost:8090' + RequestInfo.Url;
// 4. Executa a requisição real Response := RestClient .Execute(RequestInfo) // Método que aceita o objeto do parser! .Await;
// 5. Valida a resposta Should(Response.StatusCode).Be(201); Should(Response.ContentString).Contain('"status":"created"');
finally Requests.Free; end; finally Server.Stop; Server.Free; end;end;Isso é End-to-End Testing elegante. Seu arquivo .http serve como documentação viva e como driver para seus testes automatizados.
8. Comece Hoje no Seu Legado (VCL/FMX)
Seção intitulada “8. Comece Hoje no Seu Legado (VCL/FMX)”Talvez você esteja pensando: “Isso é lindo, mas meu sistema é um ERP Desktop monolítico de 10 anos, não posso reescrever tudo para Web agora”.
A boa notícia: Você não precisa.
O Dext.Net.RestClient é totalmente desacoplado. Você pode começar a usá-lo hoje no seu projeto VCL ou FMX e começar a substituir aquelas chamadas HTTP verbosas aos poucos.
Não precisa migrar o banco de dados, não precisa criar Controllers. Apenas adicione a unit ao uses e comece a escrever código novo (ou refatorizar o antigo) com qualidade moderna. É a porta de entrada perfeita para modernizar seu stack sem o risco de uma reescrita total.
Epílogo: “Isso é mesmo Delphi?”
Seção intitulada “Epílogo: “Isso é mesmo Delphi?””Se você chegou até aqui, viu injeção de dependência, expressions, generics, programação assíncrona real e testes fluentes.
Se eu tivesse escondido as palavras-chave begin/end, você provavelmente juraria que estava lendo um artigo sobre C# ou TypeScript, não é? Pois é. O Delphi evoluiu. E com o Dext Framework, nós garantimos que o seu código evolua junto.
Conclusão e Call to Action
Seção intitulada “Conclusão e Call to Action”O Dext.Net.RestClient não é apenas um wrapper HTTP; é uma modernização da forma como pensamos em conectividade no Delphi. Ele une a segurança de tipos do Pascal, a elegância de APIs fluentes e o poder do assincronismo moderno.
Este projeto é Open Source e feito pela comunidade, para a comunidade.
Se você gostou do que viu e quer apoiar essa evolução do ecossistema Delphi, visite nosso repositório e deixe uma Estrela ⭐. Isso nos ajuda muito a continuar construindo ferramentas de alto nível para você.
👉 Dê uma ⭐ no GitHub agora: github.com/cesarliws/dext
Quer dominar a Assincronia no Delphi?
Seção intitulada “Quer dominar a Assincronia no Delphi?”Para entender profundamente como o Dext.Threading (o motor por trás deste Rest Client) funciona, confira meu novo livro: