O problema: a maioria das APIs modernas entrega uma spec OpenAPI, não um SDK Delphi
Se você já integrou uma API REST moderna em Delphi, o fluxo provavelmente foi assim: ler a documentação, escrever à mão um wrapper sobre TIdHTTP ou TNetHTTPClient, colar corpos de requisição em literais de string, analisar respostas com TJSONObject, brigar com a serialização de TDateTime, repetir para cada endpoint. Funciona, mas não escala. A API tem 80 endpoints, você embrulha 8 deles, o fornecedor adiciona mais 10 no mês seguinte e seu wrapper apodrece.
A promessa do OpenAPI (antigo Swagger) é que o fornecedor publica uma descrição legível por máquina — um único arquivo YAML ou JSON — e um gerador a transforma em um cliente tipado na sua linguagem de escolha. Para a maioria das linguagens isso funciona extremamente bem: openapi-generator e swagger-codegen produzem clientes idiomáticos para Python, TypeScript, Go, Java, C#, Rust e muitas outras.
Para Delphi a história tem sido historicamente menos suave. Este post compara as duas opções principais em 2026 — o tradicional gerador Delphi open-source swagger-codegen e o nativo comercial sgcOpenAPI da eSeGeCe — e mostra o que cada um produz a partir do mesmo arquivo de spec.
Sobre o swagger-codegen e o openapi-generator
O projeto Swagger, agora sob a guarda da SmartBear, fornece o swagger-codegen. Após um fork da comunidade em 2018, um projeto paralelo, o openapi-generator, tornou-se o padrão de fato para muitas linguagens. Ambas as ferramentas suportam uma longa lista de linguagens-alvo via templates Mustache. Um gerador Delphi (delphi no swagger-codegen, mais templates da comunidade) existe, mas sempre foi um alvo de segunda categoria, mantido por voluntários ocasionais.
Na data de publicação, o template Delphi do openapi-generator gera código que compila em versões mais antigas do Delphi, mas tem problemas conhecidos em versões modernas (D11/D12/D13): tratamento incorreto de campos nullable, ausência de guards {$IFDEF} para a RTL mais nova, falta de suporte ao OpenAPI 3.1, falta de suporte a respostas em streaming e um runtime que depende de uma versão específica de biblioteca cliente HTTP. Várias das issues de longa data abertas no GitHub contra o gerador Delphi estão pendentes há anos. Seus resultados podem variar conforme a spec.
Sobre o sgcOpenAPI
O sgcOpenAPI é uma ferramenta nativa em Delphi da eSeGeCe. Ela faz parse de specs OpenAPI 3.0 (e agora 3.1) e emite units Delphi que seguem as convenções de nomenclatura sgc: Tsgc[Api]Client para o cliente, Tsgc[Api]_[Model] para cada objeto de schema e um método por operação. O código gerado usa o TsgcHTTPComponentClient do sgcWebSockets como transporte, então autenticação, retry, TLS e HTTP/2 são herdados de graça.
Como o gerador é, ele mesmo, escrito em Delphi, pode ser embutido em uma ferramenta Delphi, executado pela linha de comando ou invocado por um script de build. A saída são arquivos .pas simples, sem dependência de runtime além do sgcWebSockets — sem JVM, sem Node, sem Python, sem template engine.
Comparação de recursos
| Recurso | swagger-codegen / openapi-generator (alvo Delphi) | sgcOpenAPI |
|---|---|---|
| OpenAPI 2.0 (Swagger) | Sim | Sim |
| OpenAPI 3.0 | Sim (openapi-generator) | Sim |
| OpenAPI 3.1 | Limitado na data de publicação | Sim |
| Requisito de runtime | Java 11+ para rodar o gerador | Nenhum (exe nativo Delphi) |
| Versões Delphi alvo | Best effort em D10.x, frequentemente quebrado em D11+ na data de publicação | D7 até D13 |
| Backend HTTP | Indy por padrão nos templates Delphi atuais | sgcHTTPComponentClient (Indy / ICS / SChannel, mais HTTP/2) |
| Respostas async / streaming | Limitado | Sim |
| Autenticação OAuth2 / API key / bearer | Parcial | Sim, componentes nativos |
Polimorfismo (oneOf, allOf, discriminator) | Limitado | Sim |
| Campos nullable | Inconsistente | Sim (TsgcNullable<T>) |
| Upload de arquivos / multipart | Parcial | Sim |
| Geração de stubs de servidor | Sim (principalmente em outras linguagens) | Sim (stubs de servidor Delphi com sgcWebSocketHTTPServer) |
| Licença | Open source (Apache 2.0) | Comercial |
Comparação de fluxo de trabalho
Fluxo do swagger-codegen
- Instale o Java 11 ou superior.
- Baixe o JAR do
openapi-generator-cli. - Rode
java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out. - Abra os arquivos
.pasgerados no seu IDE. Adicione o caminho do runtime do Indy. Corrija eventuais problemas de compilação para sua versão do Delphi. Ajuste o tratamento de nullables. Reexecute a cada mudança de spec. - O cliente gerado depende de uma unit de suporte separada, distribuída pelo template. Você distribui essa unit junto com seu projeto.
Fluxo do sgcOpenAPI
- Abra a IDE do sgcOpenAPI ou chame a CLI:
sgcOpenAPI.exe -i spec.yaml -o ./out. - Abra a unit gerada na IDE. Ela usa o
TsgcHTTPComponentClient, que você já tem se usa sgcWebSockets. - Arraste o componente cliente gerado para um form, defina a URL base e as credenciais, e chame os métodos tipados.
Lado a lado: um método GET /users/{id} gerado
O mesmo fragmento OpenAPI, as duas ferramentas, a mesma operação. Nomes de helpers e formatação exata foram levemente estilizados para clareza, mas as diferenças de abordagem são reais.
swagger-codegen (alvo Delphi, simplificado)
function TUsersApi.GetUserById(const Id: Int64): TUser;
var
HttpRequest: TIdHTTP;
Path, Response: string;
JsonValue: TJSONValue;
begin
Path := StringReplace(BasePath + '/users/{id}', '{id}', IntToStr(Id), [rfReplaceAll]);
HttpRequest := TIdHTTP.Create(nil);
try
HttpRequest.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + FApiKey);
Response := HttpRequest.Get(Path);
finally
HttpRequest.Free;
end;
JsonValue := TJSONObject.ParseJSONValue(Response);
try
Result := TUser.Create;
Result.Id := (JsonValue as TJSONObject).GetValue<Int64>('id');
Result.Name := (JsonValue as TJSONObject).GetValue<string>('name');
// ... nullable fields handled inconsistently ...
finally
JsonValue.Free;
end;
end;
sgcOpenAPI
function TsgcUsersApiClient.GetUserById(const aId: Int64): TsgcUser;
var
vResponse: TsgcAPIResponse;
begin
Result := nil;
vResponse := DoGet(Format('/users/%d', [aId]));
Try
if vResponse.StatusCode = 200 then
Result := TsgcUser.FromJSON(vResponse.Content);
Finally
vResponse.Free;
End;
end;
// TsgcUser is generated with typed nullable fields:
// property Id: Int64 read FId write FId;
// property Name: string read FName write FName;
// property Email: TsgcNullable<string> read FEmail write FEmail;
// property CreatedAt: TDateTime read FCreatedAt write FCreatedAt;
//
// Authentication, retry, HTTP/2, TLS are configured on the
// underlying TsgcHTTPComponentClient once, not per-method.
Diferenças que vale destacar:
- O sgcOpenAPI separa transporte (configurações em nível de componente) das operações (métodos tipados), de modo que autenticação, retry e TLS são configurados uma única vez.
- Campos nullable usam um wrapper tipado
TsgcNullable<T>que distingue entre “ausente”, “null” e “valor” — alinhado à semântica do OpenAPI 3.x. - Campos de data/hora usam
TDateTimereal com o parser ISO 8601 correto, não uma string que você analisa depois. - O cliente gerado usa o componente HTTP do sgcWebSockets, que suporta HTTP/2 de forma transparente se o servidor anunciar via ALPN.
Stubs de servidor
As duas ferramentas também conseguem gerar código do lado servidor, mas os templates Delphi de servidor no openapi-generator são mínimos na data de publicação. O sgcOpenAPI gera um handler baseado em TsgcWebSocketHTTPServer com um método virtual por operação, validação de requisição, modelagem de resposta e um endpoint embutido de explorador OpenAPI. Para serviços internos em que você quer que um único projeto Delphi exponha a API e um cliente Delphi a consuma, o ciclo de ida e volta fica muito curto.
Quando o swagger-codegen ainda é a escolha certa
- Você já está padronizado em
openapi-generatorem várias linguagens e quer uma única ferramenta no seu pipeline de CI. - Sua spec é pequena e estável e você não precisa de recursos do OpenAPI 3.1.
- Você está confortável aplicando patches no Delphi gerado para se adequar à sua versão alvo.
- Você não pode usar software comercial por questões de licença.
Quando o sgcOpenAPI economiza tempo real
- Você está em uma versão atual do Delphi (D11 / D12 / D13) onde o template Delphi do swagger-codegen anda meio enferrujado na data de publicação.
- Sua spec usa OpenAPI 3.1,
oneOf/discriminator, campos nullable, upload de arquivos ou streaming assíncrono. - Você já usa sgcWebSockets e quer um modelo de componentes consistente e uma única stack HTTP.
- Você precisa que HTTP/2, TLS, OAuth2 e retry “simplesmente funcionem”, sem reescrever o cliente gerado.
Considerações finais
Gerar código a partir do OpenAPI é um daqueles ganhos de produtividade que se acumulam ao longo da vida de um projeto — desde que o gerador acompanhe a spec e a sua versão do Delphi. swagger-codegen / openapi-generator são excelentes ferramentas multilíngue, mas o alvo Delphi historicamente foi tratado como best-effort. O sgcOpenAPI é uma alternativa focada, nativa em Delphi, que entrega clientes (e stubs de servidor) OpenAPI 3.0 / 3.1 compiláveis, idiomáticos e com recursos completos, sem dependência de Java e sem o ciclo de patches manuais. Para a maioria das equipes Delphi que já integram APIs REST, o investimento se paga na primeira vez em que um fornecedor atualiza a spec.