The problem: most modern APIs ship an OpenAPI spec, not a Delphi SDK
If you have ever integrated a modern REST API in Delphi, the workflow probably looked like this: read the docs, hand-write a wrapper around TIdHTTP or TNetHTTPClient, paste request bodies into string literals, parse responses with TJSONObject, fight with TDateTime serialisation, repeat for every endpoint. It works but it does not scale. The API has 80 endpoints, you wrap 8 of them, the vendor adds 10 more next month, and your wrapper rots.
The promise of OpenAPI (formerly Swagger) is that the vendor publishes a machine-readable description — one YAML or JSON file — and a generator turns it into a typed client in your language of choice. For most languages this works extremely well: openapi-generator and swagger-codegen produce idiomatic clients for Python, TypeScript, Go, Java, C#, Rust and many others.
For Delphi the story has historically been less smooth. This post compares the two main options as of 2026 — the long-standing open-source swagger-codegen Delphi generator and the native commercial sgcOpenAPI from eSeGeCe — and shows what each produces from the same input spec.
About swagger-codegen and openapi-generator
The Swagger project, now under the SmartBear umbrella, ships swagger-codegen. After a community fork in 2018 a parallel project, openapi-generator, became the de facto standard for many languages. Both tools support a long list of target languages via Mustache templates. A Delphi generator (delphi in swagger-codegen, plus community templates) exists, but it has always been a second-tier target maintained by occasional volunteers.
As of writing, the Delphi template in openapi-generator generates code that compiles on older Delphi versions but has known issues on modern Delphi (D11/D12/D13): incorrect handling of nullable fields, missing {$IFDEF} guards for newer RTL, no support for OpenAPI 3.1, no streaming response support, and a runtime that depends on a particular HTTP client library version. Several of the long-standing GitHub issues against the Delphi generator have been open for years. Your mileage will vary by spec.
About sgcOpenAPI
sgcOpenAPI is a native Delphi tool from eSeGeCe. It parses OpenAPI 3.0 (and now 3.1) specifications and emits Delphi units that follow sgc naming conventions: Tsgc[Api]Client for the client, Tsgc[Api]_[Model] for each schema object, and one method per operation. The generated code uses TsgcHTTPComponentClient from sgcWebSockets as the transport, so authentication, retry, TLS and HTTP/2 are inherited for free.
Because the generator is itself written in Delphi, it can be embedded in a Delphi tool, run from the command line, or invoked from a build script. The output is plain .pas files with no runtime dependency beyond sgcWebSockets — no JVM, no Node, no Python, no template engine.
Feature comparison
| Feature | swagger-codegen / openapi-generator (Delphi target) | sgcOpenAPI |
|---|---|---|
| OpenAPI 2.0 (Swagger) | Yes | Yes |
| OpenAPI 3.0 | Yes (openapi-generator) | Yes |
| OpenAPI 3.1 | Limited as of writing | Yes |
| Runtime requirement | Java 11+ to run the generator | None (native Delphi exe) |
| Target Delphi versions | Best effort on D10.x, often broken on D11+ as of writing | D7 through D13 |
| HTTP backend | Indy by default in current Delphi templates | sgcHTTPComponentClient (Indy / ICS / SChannel, plus HTTP/2) |
| Async / streaming responses | Limited | Yes |
| OAuth2 / API key / bearer auth | Partial | Yes, native components |
Polymorphism (oneOf, allOf, discriminator) | Limited | Yes |
| Nullable fields | Inconsistent | Yes (TsgcNullable<T>) |
| File upload / multipart | Partial | Yes |
| Server stub generation | Yes (other languages mostly) | Yes (Delphi server stubs with sgcWebSocketHTTPServer) |
| License | Open source (Apache 2.0) | Commercial |
Workflow comparison
swagger-codegen workflow
- Install Java 11 or newer.
- Download the
openapi-generator-cliJAR. - Run
java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out. - Open the generated
.pasfiles in your IDE. Add the Indy runtime path. Fix any compilation issues for your Delphi version. Patch nullable handling. Re-run after every spec change. - The generated client depends on a separate runtime support unit shipped by the template. You ship that unit with your project.
sgcOpenAPI workflow
- Open sgcOpenAPI IDE or call the CLI:
sgcOpenAPI.exe -i spec.yaml -o ./out. - Open the generated unit in the IDE. It uses
TsgcHTTPComponentClientwhich you already have if you use sgcWebSockets. - Drop the generated client component on a form, set the base URL and credentials, and call the typed methods.
Side-by-side: a generated GET /users/{id} method
Same OpenAPI fragment, both tools, identical operation. Names of helpers and exact formatting are stylised slightly for clarity but the differences in approach are real.
swagger-codegen (Delphi target, simplified)
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.
Differences worth noting:
- sgcOpenAPI separates transport (component-level settings) from operations (typed methods), so auth, retry and TLS are configured once.
- Nullable fields use a typed wrapper
TsgcNullable<T>that distinguishes “absent”, “null” and “value” — matching the OpenAPI 3.x semantics. - Date/time fields use real
TDateTimewith the right ISO 8601 parser, not a string that you parse later. - The generated client uses the sgcWebSockets HTTP component, which supports HTTP/2 transparently if the server advertises it via ALPN.
Server stubs
Both tools can also generate server-side code, but the Delphi server templates in openapi-generator are minimal as of writing. sgcOpenAPI generates a TsgcWebSocketHTTPServer-based handler with one virtual method per operation, request validation, response shaping and a built-in OpenAPI explorer endpoint. For internal services where you want a single Delphi project to expose the API and a Delphi client to consume it, the round-trip is very short.
When swagger-codegen is still the right choice
- You are already standardised on
openapi-generatoracross many languages and want one tool in your CI pipeline. - Your spec is small and stable and you do not need OpenAPI 3.1 features.
- You are comfortable patching the generated Delphi to fit your target version.
- You cannot use commercial software for license reasons.
When sgcOpenAPI saves real time
- You are on a current Delphi version (D11 / D12 / D13) where the swagger-codegen Delphi template is creaky as of writing.
- Your spec uses OpenAPI 3.1,
oneOf/discriminator, nullable fields, file uploads, or async streaming. - You already use sgcWebSockets and want a consistent component model and a single HTTP stack.
- You need HTTP/2, TLS, OAuth2 and retry to “just work” without rewriting the generated client.
Closing thoughts
Code generation from OpenAPI is one of those productivity wins that compounds over the life of a project — provided the generator keeps pace with the spec and with your Delphi version. swagger-codegen / openapi-generator are excellent multi-language tools, but their Delphi target has historically been treated as best-effort. sgcOpenAPI is a focused, native Delphi alternative that delivers compilable, idiomatic, full-feature OpenAPI 3.0 / 3.1 clients (and server stubs) without a Java dependency and without the manual patching cycle. For most Delphi teams already integrating REST APIs, it pays for itself the first time a vendor updates their spec.