sgcOpenAPI vs Swagger Codegen — Gere clientes Delphi mais rápido

· Análises

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

Recursoswagger-codegen / openapi-generator (alvo Delphi)sgcOpenAPI
OpenAPI 2.0 (Swagger)SimSim
OpenAPI 3.0Sim (openapi-generator)Sim
OpenAPI 3.1Limitado na data de publicaçãoSim
Requisito de runtimeJava 11+ para rodar o geradorNenhum (exe nativo Delphi)
Versões Delphi alvoBest effort em D10.x, frequentemente quebrado em D11+ na data de publicaçãoD7 até D13
Backend HTTPIndy por padrão nos templates Delphi atuaissgcHTTPComponentClient (Indy / ICS / SChannel, mais HTTP/2)
Respostas async / streamingLimitadoSim
Autenticação OAuth2 / API key / bearerParcialSim, componentes nativos
Polimorfismo (oneOf, allOf, discriminator)LimitadoSim
Campos nullableInconsistenteSim (TsgcNullable<T>)
Upload de arquivos / multipartParcialSim
Geração de stubs de servidorSim (principalmente em outras linguagens)Sim (stubs de servidor Delphi com sgcWebSocketHTTPServer)
LicençaOpen source (Apache 2.0)Comercial

Comparação de fluxo de trabalho

Fluxo do swagger-codegen

  1. Instale o Java 11 ou superior.
  2. Baixe o JAR do openapi-generator-cli.
  3. Rode java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out.
  4. Abra os arquivos .pas gerados 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.
  5. 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

  1. Abra a IDE do sgcOpenAPI ou chame a CLI: sgcOpenAPI.exe -i spec.yaml -o ./out.
  2. Abra a unit gerada na IDE. Ela usa o TsgcHTTPComponentClient, que você já tem se usa sgcWebSockets.
  3. 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:

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

Quando o sgcOpenAPI economiza tempo real

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.