Het probleem: de meeste moderne API’s leveren een OpenAPI-spec, geen Delphi-SDK
Als je ooit een moderne REST-API in Delphi hebt geintegreerd, zag de workflow er waarschijnlijk zo uit: docs lezen, met de hand een wrapper rond TIdHTTP of TNetHTTPClient schrijven, request-bodies in string literals plakken, antwoorden parsen met TJSONObject, vechten met TDateTime-serialisatie, herhalen voor elke endpoint. Het werkt, maar het schaalt niet. De API heeft 80 endpoints, je wrapt er 8, de leverancier voegt er volgende maand 10 toe, en je wrapper vergaat.
De belofte van OpenAPI (voorheen Swagger) is dat de leverancier een machine-leesbare beschrijving publiceert — een YAML- of JSON-bestand — en een generator zet dat om in een typed client in de taal van je keuze. Voor de meeste talen werkt dit uitstekend: openapi-generator en swagger-codegen produceren idiomatische clients voor Python, TypeScript, Go, Java, C#, Rust en vele andere.
Voor Delphi is dat verhaal historisch gezien minder soepel geweest. Dit bericht vergelijkt de twee belangrijkste opties per 2026 — de al lang bestaande open-source swagger-codegen Delphi-generator en de native commerciele sgcOpenAPI van eSeGeCe — en laat zien wat elk produceert uit dezelfde input-spec.
Over swagger-codegen en openapi-generator
Het Swagger-project, nu onder de SmartBear-paraplu, levert swagger-codegen. Na een community-fork in 2018 werd een parallel project, openapi-generator, de facto standaard voor veel talen. Beide tools ondersteunen een lange lijst doel-talen via Mustache templates. Een Delphi-generator (delphi in swagger-codegen, plus community templates) bestaat, maar is altijd een tweederangs doel geweest, onderhouden door incidentele vrijwilligers.
Op het moment van schrijven genereert het Delphi-template in openapi-generator code die compileert op oudere Delphi-versies maar bekende problemen heeft op moderne Delphi (D11/D12/D13): onjuiste afhandeling van nullable velden, ontbrekende {$IFDEF}-guards voor nieuwere RTL, geen ondersteuning voor OpenAPI 3.1, geen streaming response-ondersteuning, en een runtime die afhangt van een specifieke HTTP-client bibliotheekversie. Diverse al lang bestaande GitHub-issues tegen de Delphi-generator staan al jaren open. Je ervaring zal varieren per spec.
Over sgcOpenAPI
sgcOpenAPI is een native Delphi-tool van eSeGeCe. Het parset OpenAPI 3.0 (en nu 3.1) specificaties en levert Delphi-units op die de sgc-naamgevingsconventies volgen: Tsgc[Api]Client voor de client, Tsgc[Api]_[Model] voor elk schema-object, en een methode per operation. De gegenereerde code gebruikt TsgcHTTPComponentClient uit sgcWebSockets als transport, dus authenticatie, retry, TLS en HTTP/2 worden gratis geerfd.
Omdat de generator zelf in Delphi is geschreven, kan hij worden ingebed in een Delphi-tool, vanaf de command line worden uitgevoerd of vanuit een build script worden aangeroepen. De output is gewone .pas-bestanden zonder runtime-afhankelijkheid buiten sgcWebSockets — geen JVM, geen Node, geen Python, geen template engine.
Feature-vergelijking
| Feature | swagger-codegen / openapi-generator (Delphi-target) | sgcOpenAPI |
|---|---|---|
| OpenAPI 2.0 (Swagger) | Ja | Ja |
| OpenAPI 3.0 | Ja (openapi-generator) | Ja |
| OpenAPI 3.1 | Beperkt op moment van schrijven | Ja |
| Runtime-vereiste | Java 11+ om de generator te draaien | Geen (native Delphi-exe) |
| Doel-Delphi-versies | Best effort op D10.x, vaak gebroken op D11+ op moment van schrijven | D7 t/m D13 |
| HTTP-backend | Indy standaard in huidige Delphi-templates | sgcHTTPComponentClient (Indy / ICS / SChannel, plus HTTP/2) |
| Async / streaming responses | Beperkt | Ja |
| OAuth2 / API key / bearer auth | Gedeeltelijk | Ja, native componenten |
Polymorfie (oneOf, allOf, discriminator) | Beperkt | Ja |
| Nullable velden | Inconsistent | Ja (TsgcNullable<T>) |
| Bestandsupload / multipart | Gedeeltelijk | Ja |
| Server stub-generatie | Ja (vooral andere talen) | Ja (Delphi server stubs met sgcWebSocketHTTPServer) |
| Licentie | Open source (Apache 2.0) | Commercieel |
Workflow-vergelijking
swagger-codegen workflow
- Installeer Java 11 of nieuwer.
- Download de
openapi-generator-cliJAR. - Voer
java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./outuit. - Open de gegenereerde
.pas-bestanden in je IDE. Voeg het Indy-runtime-pad toe. Los eventuele compilatieproblemen voor je Delphi-versie op. Patch nullable-afhandeling. Voer opnieuw uit na elke spec-wijziging. - De gegenereerde client hangt af van een aparte runtime support-unit die door het template wordt geleverd. Je verzendt die unit mee met je project.
sgcOpenAPI workflow
- Open de sgcOpenAPI-IDE of roep de CLI aan:
sgcOpenAPI.exe -i spec.yaml -o ./out. - Open de gegenereerde unit in de IDE. Hij gebruikt
TsgcHTTPComponentClientdie je al hebt als je sgcWebSockets gebruikt. - Plaats de gegenereerde client-component op een formulier, stel de base-URL en credentials in, en roep de typed methodes aan.
Side-by-side: een gegenereerde GET /users/{id}-methode
Hetzelfde OpenAPI-fragment, beide tools, identieke operation. Namen van helpers en exacte formattering zijn licht gestileerd voor duidelijkheid maar de verschillen in aanpak zijn reeel.
swagger-codegen (Delphi-target, vereenvoudigd)
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.
Verschillen die het noemen waard zijn:
- sgcOpenAPI scheidt transport (component-niveau-instellingen) van operations (typed methodes), zodat auth, retry en TLS eenmalig worden geconfigureerd.
- Nullable velden gebruiken een typed wrapper
TsgcNullable<T>die “afwezig”, “null” en “waarde” onderscheidt — passend bij de OpenAPI 3.x-semantiek. - Datum/tijd-velden gebruiken echte
TDateTimemet de juiste ISO 8601-parser, geen string die je later parset. - De gegenereerde client gebruikt de sgcWebSockets HTTP-component, die HTTP/2 transparant ondersteunt als de server het via ALPN adverteert.
Server stubs
Beide tools kunnen ook server-side code genereren, maar de Delphi server-templates in openapi-generator zijn op moment van schrijven minimaal. sgcOpenAPI genereert een op TsgcWebSocketHTTPServer gebaseerde handler met een virtuele methode per operation, request-validatie, response-shaping en een ingebouwd OpenAPI-explorer-endpoint. Voor interne services waar je een enkel Delphi-project de API wilt laten exposen en een Delphi-client wilt laten consumeren, is de round-trip zeer kort.
Wanneer swagger-codegen nog de juiste keuze is
- Je bent al gestandaardiseerd op
openapi-generatorin meerdere talen en wilt een tool in je CI-pipeline. - Je spec is klein en stabiel en je hebt geen OpenAPI 3.1-features nodig.
- Je kunt comfortabel de gegenereerde Delphi patchen om bij je doelversie te passen.
- Je kunt om licentieredenen geen commerciele software gebruiken.
Wanneer sgcOpenAPI echte tijd bespaart
- Je zit op een actuele Delphi-versie (D11 / D12 / D13) waar het swagger-codegen Delphi-template krakkemikkig is op moment van schrijven.
- Je spec gebruikt OpenAPI 3.1,
oneOf/discriminator, nullable velden, bestandsuploads of async streaming. - Je gebruikt al sgcWebSockets en wilt een consistent componentmodel en een enkele HTTP-stack.
- Je hebt nodig dat HTTP/2, TLS, OAuth2 en retry “gewoon werken” zonder de gegenereerde client te herschrijven.
Afsluitende gedachten
Code-generatie vanuit OpenAPI is een van die productiviteitswinsten die zich opstapelt over de levensduur van een project — mits de generator de spec en je Delphi-versie bijhoudt. swagger-codegen / openapi-generator zijn uitstekende multi-language tools, maar hun Delphi-target is historisch als best-effort behandeld. sgcOpenAPI is een gerichte, native Delphi-alternatief dat compileerbare, idiomatische, full-feature OpenAPI 3.0 / 3.1-clients (en server stubs) levert zonder Java-afhankelijkheid en zonder de handmatige patch-cyclus. Voor de meeste Delphi-teams die al REST-API’s integreren, verdient het zich de eerste keer terug dat een leverancier zijn spec bijwerkt.