sgcOpenAPI vs Swagger Codegen — Generuj klientów Delphi szybciej

· Recenzje

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

Funkcjaswagger-codegen / openapi-generator (cel Delphi)sgcOpenAPI
OpenAPI 2.0 (Swagger)TakTak
OpenAPI 3.0Tak (openapi-generator)Tak
OpenAPI 3.1Ograniczone na dzień pisaniaTak
Wymóg runtimeJava 11+ do uruchomienia generatoraBrak (natywny exe Delphi)
Docelowe wersje DelphiNajlepszy wysiłek na D10.x, często złamane na D11+ na dzień pisaniaD7 do D13
Backend HTTPIndy domyślnie w bieżących szablonach DelphisgcHTTPComponentClient (Indy / ICS / SChannel, plus HTTP/2)
Odpowiedzi asynchroniczne / strumienioweOgraniczoneTak
Uwierzytelnianie OAuth2 / API key / bearerCzęścioweTak, natywne komponenty
Polimorfizm (oneOf, allOf, discriminator)OgraniczoneTak
Pola nullableNiespójneTak (TsgcNullable<T>)
Upload plików / multipartCzęścioweTak
Generowanie stubów serweraTak (głównie inne języki)Tak (stuby serwera Delphi z sgcWebSocketHTTPServer)
LicencjaOpen source (Apache 2.0)Komercyjna

Porównanie przepływu pracy

Przepływ swagger-codegen

  1. Zainstaluj Javę 11 lub nowszą.
  2. Pobierz JAR openapi-generator-cli.
  3. Uruchom java -jar openapi-generator-cli.jar generate -i spec.yaml -g delphi -o ./out.
  4. Otwórz wygenerowane pliki .pas w 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.
  5. Wygenerowany klient zależy od oddzielnej jednostki wsparcia runtime dostarczonej przez szablon. Dostarczasz tę jednostkę ze swoim projektem.

Przepływ sgcOpenAPI

  1. Otwórz IDE sgcOpenAPI lub wywołaj CLI: sgcOpenAPI.exe -i spec.yaml -o ./out.
  2. Otwórz wygenerowaną jednostkę w IDE. Używa TsgcHTTPComponentClient, który już masz, jeśli używasz sgcWebSockets.
  3. 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:

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

Kiedy sgcOpenAPI oszczędza realny czas

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ę.