sgcOpenAPI vs. Swagger Codegen — Delphi-Clients schneller generieren

· Reviews

Das Problem: Die meisten modernen APIs liefern eine OpenAPI-Spezifikation, kein Delphi-SDK

Wenn du je eine moderne REST-API in Delphi integriert hast, sah der Workflow vermutlich so aus: Doku lesen, einen Wrapper um TIdHTTP oder TNetHTTPClient handschriftlich basteln, Request-Bodies in String-Literale kopieren, Antworten mit TJSONObject parsen, mit der TDateTime-Serialisierung kämpfen, für jeden Endpunkt wiederholen. Es funktioniert, skaliert aber nicht. Die API hat 80 Endpunkte, du wrappst 8, der Hersteller fügt nächsten Monat 10 weitere hinzu und dein Wrapper verrottet.

Das Versprechen von OpenAPI (früher Swagger) ist: Der Hersteller veröffentlicht eine maschinenlesbare Beschreibung — eine YAML- oder JSON-Datei — und ein Generator macht daraus einen typisierten Client in deiner Wunschsprache. Für die meisten Sprachen funktioniert das hervorragend: openapi-generator und swagger-codegen erzeugen idiomatische Clients für Python, TypeScript, Go, Java, C#, Rust und viele andere.

Für Delphi war diese Geschichte historisch weniger glatt. Dieser Beitrag vergleicht die beiden Hauptoptionen Stand 2026 — den seit Langem bestehenden Open-Source-swagger-codegen-Delphi-Generator und das native kommerzielle sgcOpenAPI von eSeGeCe — und zeigt, was jedes Werkzeug aus derselben Spezifikation produziert.

Zu swagger-codegen und openapi-generator

Das Swagger-Projekt, heute unter dem SmartBear-Dach, liefert swagger-codegen. Nach einem Community-Fork 2018 wurde das parallele Projekt openapi-generator für viele Sprachen zum De-facto-Standard. Beide unterstützen über Mustache-Templates eine lange Liste von Zielsprachen. Einen Delphi-Generator (delphi in swagger-codegen plus Community-Templates) gibt es, aber er war immer ein Second-Tier-Target, das von gelegentlichen Freiwilligen gepflegt wurde.

Zum Schreibzeitpunkt erzeugt das Delphi-Template im openapi-generator Code, der auf älteren Delphi-Versionen kompiliert, auf modernem Delphi (D11/D12/D13) aber bekannte Probleme hat: falsche Behandlung nullbarer Felder, fehlende {$IFDEF}-Guards für neuere RTL, keine OpenAPI-3.1-Unterstützung, kein Streaming-Response-Support und eine Laufzeit, die von einer bestimmten HTTP-Client-Bibliotheksversion abhängt. Mehrere langjährige GitHub-Issues gegen den Delphi-Generator sind seit Jahren offen. Die Erfahrung variiert je nach Spezifikation.

Zu sgcOpenAPI

sgcOpenAPI ist ein natives Delphi-Werkzeug von eSeGeCe. Es parst OpenAPI 3.0 (und inzwischen 3.1) und emittiert Delphi-Units, die den sgc-Namenskonventionen folgen: Tsgc[Api]Client für den Client, Tsgc[Api]_[Model] pro Schemaobjekt und eine Methode pro Operation. Der generierte Code nutzt TsgcHTTPComponentClient aus sgcWebSockets als Transport — Authentifizierung, Retry, TLS und HTTP/2 erbst du kostenlos.

Weil der Generator selbst in Delphi geschrieben ist, kann er in ein Delphi-Werkzeug eingebettet, von der Kommandozeile ausgeführt oder aus einem Build-Skript aufgerufen werden. Die Ausgabe sind reine .pas-Dateien ohne Laufzeit­abhängigkeit über sgcWebSockets hinaus — keine JVM, kein Node, kein Python, keine Template-Engine.

Feature-Vergleich

Featureswagger-codegen / openapi-generator (Delphi-Target)sgcOpenAPI
OpenAPI 2.0 (Swagger)JaJa
OpenAPI 3.0Ja (openapi-generator)Ja
OpenAPI 3.1Eingeschränkt zum SchreibzeitpunktJa
LaufzeitanforderungJava 11+, um den Generator auszuführenKeine (native Delphi-EXE)
Ziel-Delphi-VersionenBest Effort auf D10.x, oft kaputt ab D11 zum SchreibzeitpunktD7 bis D13
HTTP-BackendStandardmäßig Indy in aktuellen Delphi-TemplatessgcHTTPComponentClient (Indy / ICS / SChannel, plus HTTP/2)
Async-/Streaming-AntwortenEingeschränktJa
OAuth2 / API-Key / Bearer-AuthTeilweiseJa, native Komponenten
Polymorphie (oneOf, allOf, discriminator)EingeschränktJa
Nullbare FelderInkonsistentJa (TsgcNullable<T>)
File-Upload / MultipartTeilweiseJa
Server-Stub-GenerierungJa (vor allem andere Sprachen)Ja (Delphi-Server-Stubs mit sgcWebSocketHTTPServer)
LizenzOpen Source (Apache 2.0)Kommerziell

Workflow-Vergleich

swagger-codegen-Workflow

  1. Java 11 oder neuer installieren.
  2. Die JAR openapi-generator-cli herunterladen.
  3. java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out ausführen.
  4. Die generierten .pas-Dateien in der IDE öffnen. Den Indy-Laufzeitpfad ergänzen. Kompilierfehler für deine Delphi-Version beheben. Nullable-Handling patchen. Nach jeder Spec-Änderung wiederholen.
  5. Der generierte Client hängt an einer separaten Runtime-Support-Unit, die das Template mitliefert. Diese Unit lieferst du mit deinem Projekt aus.

sgcOpenAPI-Workflow

  1. sgcOpenAPI-IDE öffnen oder die CLI aufrufen: sgcOpenAPI.exe -i spec.yaml -o ./out.
  2. Die generierte Unit in der IDE öffnen. Sie verwendet TsgcHTTPComponentClient, das du bereits hast, wenn du sgcWebSockets nutzt.
  3. Die generierte Client-Komponente auf ein Formular ziehen, Basis-URL und Credentials setzen und die typisierten Methoden aufrufen.

Direkt verglichen: eine generierte GET /users/{id}-Methode

Dieselbe OpenAPI-Spezifikation, beide Werkzeuge, identische Operation. Helfer-Namen und exakte Formatierung sind der Klarheit halber leicht stilisiert, die Unterschiede im Ansatz sind aber real.

swagger-codegen (Delphi-Target, vereinfacht)

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.

Bemerkenswerte Unterschiede:

Server-Stubs

Beide Werkzeuge können auch Server-seitigen Code generieren, aber die Delphi-Server-Templates in openapi-generator sind zum Schreibzeitpunkt minimal. sgcOpenAPI erzeugt einen TsgcWebSocketHTTPServer-basierten Handler mit einer virtuellen Methode pro Operation, Request-Validierung, Response-Formung und einem eingebauten OpenAPI-Explorer-Endpunkt. Für interne Dienste, in denen ein einzelnes Delphi-Projekt die API exponieren und ein Delphi-Client sie konsumieren soll, ist der Round-Trip sehr kurz.

Wann swagger-codegen weiterhin die richtige Wahl ist

Wann sgcOpenAPI echte Zeit spart

Abschluss

Codegenerierung aus OpenAPI ist einer der Produktivitätsgewinne, die sich über die Lebensdauer eines Projekts kumulieren — vorausgesetzt, der Generator hält Schritt mit der Spezifikation und mit deiner Delphi-Version. swagger-codegen / openapi-generator sind hervorragende Multi-Sprachen-Werkzeuge, aber ihr Delphi-Target wurde historisch als Best Effort behandelt. sgcOpenAPI ist eine fokussierte, native Delphi-Alternative, die kompilierbare, idiomatische, vollwertige OpenAPI-3.0-/3.1-Clients (und Server-Stubs) liefert — ohne Java-Abhängigkeit und ohne manuellen Patch-Zyklus. Für die meisten Delphi-Teams, die bereits REST-APIs integrieren, rechnet es sich beim ersten Hersteller-Spec-Update.