Problem: większość nowoczesnych API dostarcza specyfikację OpenAPI, a nie SDK Delphi
Jeśli kiedykolwiek integrowałeś nowoczesne REST API w Delphi, przepływ pracy prawdopodobnie wyglądał tak: czytaj dokumentację, ręcznie napisz wrapper wokół TIdHTTP lub TNetHTTPClient, wklej ciała żądań do literałów stringów, parsuj odpowiedzi za pomocą TJSONObject, walcz z serializacją TDateTime, powtórz dla każdego endpointu. Działa, ale się nie skaluje. API ma 80 endpointów, owijasz 8 z nich, dostawca dodaje 10 więcej w następnym miesiącu, a Twój wrapper gnije.
Obietnica OpenAPI (wcześniej Swagger) jest taka, że dostawca publikuje opis czytelny maszynowo — jeden plik YAML lub JSON — a generator zamienia go w typowanego klienta w wybranym przez Ciebie języku. Dla większości języków działa to bardzo dobrze: openapi-generator i swagger-codegen produkują idiomatycznych klientów dla Pythona, TypeScriptu, Go, Javy, C#, Rusta i wielu innych.
Dla Delphi historia była historycznie mniej gładka. Ten wpis porównuje dwie główne opcje na 2026 rok — wieloletni open-source'owy generator Delphi swagger-codegen i natywne komercyjne sgcOpenAPI od eSeGeCe — i pokazuje, co każdy z nich produkuje z tej samej specyfikacji wejściowej.
O swagger-codegen i openapi-generator
Projekt Swagger, obecnie pod parasolem SmartBear, dostarcza swagger-codegen. Po forku społeczności w 2018 roku, równoległy projekt openapi-generator stał się de facto standardem dla wielu języków. Oba narzędzia obsługują długą listę języków docelowych przez szablony Mustache. Generator Delphi (delphi w swagger-codegen, plus szablony społeczności) istnieje, ale zawsze był celem drugiej kategorii utrzymywanym przez okazjonalnych wolontariuszy.
Na dzień pisania, szablon Delphi w openapi-generator generuje kod, który kompiluje się na starszych wersjach Delphi, ale ma znane problemy na nowoczesnym Delphi (D11/D12/D13): niepoprawna obsługa pól nullable, brak gardów {$IFDEF} dla nowszego RTL, brak wsparcia dla OpenAPI 3.1, brak wsparcia dla odpowiedzi strumieniowych i runtime, który zależy od konkretnej wersji biblioteki klienta HTTP. Kilka długoletnich problemów GitHub wobec generatora Delphi jest otwartych od lat. Twoje wyniki będą się różnić w zależności od specyfikacji.
O sgcOpenAPI
sgcOpenAPI to natywne narzędzie Delphi od eSeGeCe. Parsuje specyfikacje OpenAPI 3.0 (i teraz 3.1) i emituje jednostki Delphi zgodne z konwencjami nazewnictwa sgc: Tsgc[Api]Client dla klienta, Tsgc[Api]_[Model] dla każdego obiektu schematu i jedną metodę na operację. Wygenerowany kod używa TsgcHTTPComponentClient z sgcWebSockets jako transportu, więc uwierzytelnianie, ponowne próby, TLS i HTTP/2 są dziedziczone za darmo.
Ponieważ generator sam jest napisany w Delphi, może być osadzony w narzędziu Delphi, uruchamiany z linii poleceń lub wywoływany ze skryptu kompilacji. Wynik to zwykłe pliki .pas bez zależności runtime poza sgcWebSockets — bez JVM, bez Node, bez Pythona, bez silnika szablonów.
Porównanie funkcji
| Funkcja | swagger-codegen / openapi-generator (cel Delphi) | sgcOpenAPI |
|---|---|---|
| OpenAPI 2.0 (Swagger) | Tak | Tak |
| OpenAPI 3.0 | Tak (openapi-generator) | Tak |
| OpenAPI 3.1 | Ograniczone na dzień pisania | Tak |
| Wymóg runtime | Java 11+ do uruchomienia generatora | Brak (natywny exe Delphi) |
| Docelowe wersje Delphi | Najlepszy wysiłek na D10.x, często złamane na D11+ na dzień pisania | D7 do D13 |
| Backend HTTP | Indy domyślnie w bieżących szablonach Delphi | sgcHTTPComponentClient (Indy / ICS / SChannel, plus HTTP/2) |
| Odpowiedzi asynchroniczne / strumieniowe | Ograniczone | Tak |
| Uwierzytelnianie OAuth2 / API key / bearer | Częściowe | Tak, natywne komponenty |
Polimorfizm (oneOf, allOf, discriminator) | Ograniczone | Tak |
| Pola nullable | Niespójne | Tak (TsgcNullable<T>) |
| Upload plików / multipart | Częściowe | Tak |
| Generowanie stubów serwera | Tak (głównie inne języki) | Tak (stuby serwera Delphi z sgcWebSocketHTTPServer) |
| Licencja | Open source (Apache 2.0) | Komercyjna |
Porównanie przepływu pracy
Przepływ swagger-codegen
- Zainstaluj Javę 11 lub nowszą.
- Pobierz JAR
openapi-generator-cli. - Uruchom
java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out. - Otwórz wygenerowane pliki
.pasw swoim IDE. Dodaj ścieżkę runtime Indy. Napraw wszystkie problemy z kompilacją dla swojej wersji Delphi. Załataj obsługę nullable. Uruchom ponownie po każdej zmianie specyfikacji. - Wygenerowany klient zależy od oddzielnej jednostki wsparcia runtime dostarczonej przez szablon. Dostarczasz tę jednostkę ze swoim projektem.
Przepływ sgcOpenAPI
- Otwórz IDE sgcOpenAPI lub wywołaj CLI:
sgcOpenAPI.exe -i spec.yaml -o ./out. - Otwórz wygenerowaną jednostkę w IDE. Używa
TsgcHTTPComponentClient, który już masz, jeśli używasz sgcWebSockets. - Upuść wygenerowany komponent klienta na formularz, ustaw bazowy URL i poświadczenia i wywołaj typowane metody.
Obok siebie: wygenerowana metoda GET /users/{id}
Ten sam fragment OpenAPI, oba narzędzia, identyczna operacja. Nazwy pomocników i dokładne formatowanie są lekko stylizowane dla jasności, ale różnice w podejściu są prawdziwe.
swagger-codegen (cel Delphi, uproszczony)
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.
Różnice warte uwagi:
- sgcOpenAPI oddziela transport (ustawienia na poziomie komponentu) od operacji (typowane metody), więc auth, ponowne próby i TLS są konfigurowane raz.
- Pola nullable używają typowanego wrappera
TsgcNullable<T>, który odróżnia „nieobecny”, „null” i „wartość” — zgodnie z semantyką OpenAPI 3.x. - Pola daty/czasu używają prawdziwego
TDateTimez właściwym parserem ISO 8601, a nie stringa, który parsujesz później. - Wygenerowany klient używa komponentu HTTP sgcWebSockets, który obsługuje HTTP/2 transparentnie, jeśli serwer ogłasza go przez ALPN.
Stuby serwera
Oba narzędzia mogą również generować kod po stronie serwera, ale szablony serwera Delphi w openapi-generator są minimalne na dzień pisania. sgcOpenAPI generuje handler oparty na TsgcWebSocketHTTPServer z jedną metodą wirtualną na operację, walidacją żądań, kształtowaniem odpowiedzi i wbudowanym endpointem eksploratora OpenAPI. Dla wewnętrznych usług, w których chcesz, aby pojedynczy projekt Delphi wystawiał API, a klient Delphi je konsumował, runda jest bardzo krótka.
Kiedy swagger-codegen jest nadal właściwym wyborem
- Jesteś już ustandaryzowany na
openapi-generatorprzez wiele języków i chcesz jednego narzędzia w pipeline CI. - Twoja specyfikacja jest mała i stabilna i nie potrzebujesz funkcji OpenAPI 3.1.
- Jesteś komfortowy z łataniem wygenerowanego Delphi, by pasowało do Twojej wersji docelowej.
- Nie możesz używać oprogramowania komercyjnego z powodów licencyjnych.
Kiedy sgcOpenAPI oszczędza realny czas
- Jesteś na obecnej wersji Delphi (D11 / D12 / D13), gdzie szablon Delphi swagger-codegen jest niesprawny na dzień pisania.
- Twoja specyfikacja używa OpenAPI 3.1,
oneOf/discriminator, pól nullable, uploadu plików lub strumieniowania asynchronicznego. - Już używasz sgcWebSockets i chcesz spójnego modelu komponentów i jednego stosu HTTP.
- Potrzebujesz, by HTTP/2, TLS, OAuth2 i ponowne próby „po prostu działały” bez przepisywania wygenerowanego klienta.
Podsumowanie
Generowanie kodu z OpenAPI to jedna z tych wygranych produktywności, które się kumulują przez życie projektu — pod warunkiem, że generator nadąża za specyfikacją i z Twoją wersją Delphi. swagger-codegen / openapi-generator to doskonałe narzędzia wielojęzyczne, ale ich cel Delphi był historycznie traktowany jako best-effort. sgcOpenAPI to skoncentrowana, natywna alternatywa Delphi, która dostarcza kompilowalnych, idiomatycznych, pełnofunkcyjnych klientów OpenAPI 3.0 / 3.1 (i stubów serwera) bez zależności od Javy i bez cyklu ręcznego łatania. Dla większości zespołów Delphi już integrujących REST API, spłaca się pierwszym razem, gdy dostawca aktualizuje swoją specyfikację.