Il problema: la maggior parte delle API moderne distribuisce una specifica OpenAPI, non un SDK Delphi
Se hai mai integrato un'API REST moderna in Delphi, il workflow probabilmente assomigliava a questo: leggi la documentazione, scrivi a mano un wrapper attorno a TIdHTTP o TNetHTTPClient, incolli i body di request in literal stringa, fai il parsing delle response con TJSONObject, combatti con la serializzazione di TDateTime, ripeti per ogni endpoint. Funziona ma non scala. L'API ha 80 endpoint, ne incapsuli 8, il vendor ne aggiunge altri 10 il mese prossimo e il tuo wrapper si decompone.
La promessa di OpenAPI (in precedenza Swagger) è che il vendor pubblica una descrizione machine-readable — un singolo file YAML o JSON — e un generator la trasforma in un client tipizzato nel linguaggio che scegli. Per la maggior parte dei linguaggi funziona estremamente bene: openapi-generator e swagger-codegen producono client idiomatici per Python, TypeScript, Go, Java, C#, Rust e molti altri.
Per Delphi la storia è stata storicamente meno fluida. Questo post confronta le due opzioni principali nel 2026 — il consolidato generator Delphi open-source swagger-codegen e il commerciale nativo sgcOpenAPI di eSeGeCe — e mostra cosa ciascuno produce dalla stessa specifica di input.
A proposito di swagger-codegen e openapi-generator
Il progetto Swagger, ora sotto l'ombrello di SmartBear, distribuisce swagger-codegen. Dopo un fork della community nel 2018, un progetto parallelo, openapi-generator, è diventato lo standard de facto per molti linguaggi. Entrambi gli strumenti supportano una lunga lista di linguaggi target tramite template Mustache. Un generator Delphi (delphi in swagger-codegen, più template della community) esiste, ma è sempre stato un target di seconda fascia mantenuto da volontari occasionali.
Al momento della scrittura, il template Delphi in openapi-generator genera codice che compila su versioni Delphi più vecchie ma ha problemi noti su Delphi moderni (D11/D12/D13): gestione scorretta dei campi nullable, mancanza di guard {$IFDEF} per RTL più recenti, nessun supporto OpenAPI 3.1, nessun supporto per response in streaming e un runtime che dipende da una particolare versione di libreria client HTTP. Diverse delle issue di lunga data su GitHub contro il generator Delphi sono aperte da anni. I tuoi risultati varieranno in base alla specifica.
A proposito di sgcOpenAPI
sgcOpenAPI è uno strumento Delphi nativo di eSeGeCe. Fa il parsing di specifiche OpenAPI 3.0 (e ora 3.1) ed emette unit Delphi che seguono le convenzioni di nomi sgc: Tsgc[Api]Client per il client, Tsgc[Api]_[Model] per ogni oggetto schema, e un metodo per operazione. Il codice generato usa TsgcHTTPComponentClient da sgcWebSockets come trasporto, quindi autenticazione, retry, TLS e HTTP/2 sono ereditati gratuitamente.
Poiché il generator è esso stesso scritto in Delphi, può essere integrato in uno strumento Delphi, eseguito da riga di comando o invocato da uno script di build. L'output sono semplici file .pas senza dipendenze runtime oltre a sgcWebSockets — niente JVM, niente Node, niente Python, niente template engine.
Confronto delle funzionalità
| Funzionalità | swagger-codegen / openapi-generator (target Delphi) | sgcOpenAPI |
|---|---|---|
| OpenAPI 2.0 (Swagger) | Sì | Sì |
| OpenAPI 3.0 | Sì (openapi-generator) | Sì |
| OpenAPI 3.1 | Limitato al momento | Sì |
| Requisito runtime | Java 11+ per eseguire il generator | Nessuno (eseguibile Delphi nativo) |
| Versioni Delphi target | Best effort su D10.x, spesso rotto su D11+ al momento | Da D7 a D13 |
| Backend HTTP | Indy per default negli attuali template Delphi | sgcHTTPComponentClient (Indy / ICS / SChannel, più HTTP/2) |
| Response async / streaming | Limitato | Sì |
| Auth OAuth2 / API key / bearer | Parziale | Sì, componenti nativi |
Polimorfismo (oneOf, allOf, discriminator) | Limitato | Sì |
| Campi nullable | Incoerente | Sì (TsgcNullable<T>) |
| Upload file / multipart | Parziale | Sì |
| Generazione di stub server | Sì (per lo più altri linguaggi) | Sì (stub server Delphi con sgcWebSocketHTTPServer) |
| Licenza | Open source (Apache 2.0) | Commerciale |
Confronto del workflow
Workflow swagger-codegen
- Installa Java 11 o più recente.
- Scarica il JAR
openapi-generator-cli. - Esegui
java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out. - Apri i file
.pasgenerati nel tuo IDE. Aggiungi il percorso runtime di Indy. Sistema eventuali problemi di compilazione per la tua versione di Delphi. Patcha la gestione dei nullable. Riesegui dopo ogni cambio di specifica. - Il client generato dipende da una unit di supporto runtime separata distribuita dal template. Tu distribuisci quella unit con il tuo progetto.
Workflow sgcOpenAPI
- Apri l'IDE sgcOpenAPI o chiama la CLI:
sgcOpenAPI.exe -i spec.yaml -o ./out. - Apri la unit generata nell'IDE. Usa
TsgcHTTPComponentClientche hai già se usi sgcWebSockets. - Metti il componente client generato su una form, imposta l'URL base e le credenziali, e chiama i metodi tipizzati.
Fianco a fianco: un metodo generato GET /users/{id}
Stesso frammento OpenAPI, entrambi gli strumenti, operazione identica. I nomi degli helper e la formattazione esatta sono leggermente stilizzati per chiarezza ma le differenze di approccio sono reali.
swagger-codegen (target Delphi, semplificato)
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.
Differenze degne di nota:
- sgcOpenAPI separa il trasporto (impostazioni a livello di componente) dalle operazioni (metodi tipizzati), così auth, retry e TLS sono configurati una sola volta.
- I campi nullable usano un wrapper tipizzato
TsgcNullable<T>che distingue “assente”, “null” e “valore” — corrispondendo alla semantica OpenAPI 3.x. - I campi data/ora usano un vero
TDateTimecon il giusto parser ISO 8601, non una stringa che fai il parsing dopo. - Il client generato usa il componente HTTP di sgcWebSockets, che supporta HTTP/2 in modo trasparente se il server lo pubblicizza via ALPN.
Stub server
Entrambi gli strumenti possono generare anche codice lato server, ma i template server Delphi in openapi-generator sono minimali al momento. sgcOpenAPI genera un handler basato su TsgcWebSocketHTTPServer con un metodo virtual per operazione, validazione della request, modellazione della response e un endpoint OpenAPI explorer integrato. Per servizi interni dove vuoi un singolo progetto Delphi che esponga l'API e un client Delphi che la consumi, il round-trip è molto breve.
Quando swagger-codegen è ancora la scelta giusta
- Sei già standardizzato su
openapi-generatorattraverso molti linguaggi e vuoi un solo strumento nella tua pipeline CI. - La tua specifica è piccola e stabile e non hai bisogno delle funzionalità di OpenAPI 3.1.
- Sei a tuo agio nel patchare il Delphi generato per adattarlo alla tua versione target.
- Non puoi usare software commerciale per ragioni di licenza.
Quando sgcOpenAPI fa risparmiare tempo reale
- Sei su una versione corrente di Delphi (D11 / D12 / D13) dove il template Delphi di swagger-codegen scricchiola al momento.
- La tua specifica usa OpenAPI 3.1,
oneOf/discriminator, campi nullable, upload file o streaming async. - Usi già sgcWebSockets e vuoi un modello di componenti coerente e un singolo stack HTTP.
- Hai bisogno che HTTP/2, TLS, OAuth2 e retry “funzionino e basta” senza riscrivere il client generato.
Considerazioni finali
La generazione di codice da OpenAPI è una di quelle vittorie di produttività che si moltiplicano nell'arco della vita di un progetto — a patto che il generator tenga il passo con la specifica e con la tua versione di Delphi. swagger-codegen / openapi-generator sono eccellenti strumenti multi-linguaggio, ma il loro target Delphi è stato storicamente trattato come best-effort. sgcOpenAPI è un'alternativa focalizzata e nativa Delphi che consegna client OpenAPI 3.0 / 3.1 (e stub server) compilabili, idiomatici e completi di funzionalità senza dipendenza Java e senza il ciclo di patching manuale. Per la maggior parte dei team Delphi che già integrano API REST, si ripaga la prima volta che un vendor aggiorna la sua specifica.