sgcOpenAPI 2026.6 — Bağımsız OpenAPI Sunucusu, Spec-First veya Code-First

· Sürümler

sgcOpenAPI'nin bir sonraki sürümü (Haziran'da çıkacak olan 2026.6 sürümü) yepyeni bir bileşenle geliyor: TsgcHTTPServer_OpenAPI. Bu, yerleşik bir HTTP sunucusuyla bir OpenAPI 3.0 hizmetini barındıran, kendi kendine yeten tek bir Delphi bileşenidir. Onu bir forma bırakın, bir spec'e yönlendirin (veya RTTI öznitelikleri olan bir Delphi sınıfından bir tane üretin), Active := True ayarlayın ve otomatik olarak sunulan Swagger UI ile belgelenmiş bir REST API'niz olsun.

Öne çıkan değişiklik, sgcOpenAPI'nin bir HTTP sunucusu barındırmak için artık sgcWebSockets'e ihtiyaç duymamasıdır. Yeni bileşen tamamen sgcOpenAPI üzerinden gönderilir, paketlenir ve yüklenir. sgcWebSockets'i zaten kullanıyorsanız, önceki TsgcWSServer_API_OpenAPI bileşeni değişmeden çalışmaya devam eder; ikisi de dahili olarak aynı motoru paylaşır.

Tek bir bileşende neler elde edersiniz

TsgcHTTPServer_OpenAPI üç şeyi bir arada sunar:

Hızlı başlangıç — minimum örnek

Swagger UI ile çalışan bir OpenAPI sunucusu barındırmak için ihtiyacınız olan her şey budur:

uses
  sgcHTTPServer_OpenAPI;

var
  oServer: TsgcHTTPServer_OpenAPI;
begin
  oServer := TsgcHTTPServer_OpenAPI.Create(nil);
  try
    oServer.Bindings.Add.Port := 8080;
    oServer.LoadFromFile('petstore.json');
    oServer.OnRequest := MyOnRequest;
    oServer.Active := True;
    Readln;
  finally
    oServer.Free;
  end;
end;

Swagger UI için http://localhost:8080/docs adresine, spec için http://localhost:8080/openapi.json adresine göz atın. Spec'te tanımlanan her işlem, çözümlenmiş operationId ve tam olarak oluşturulmuş bir istek bağlamıyla MyOnRequest işleyicinize yönlendirilir.

Spec-First — mevcut bir OpenAPI 3.0 dosyasını yükleme

Zaten bir OpenAPI 3.0 JSON veya YAML dosyanız varsa (Petstore, dahili bir API sözleşmesi, taklit etmek istediğiniz bir genel şema), spec-first onu sunmanın en hızlı yoludur. LoadFromFile, spec'i okur ve ayrıştırır, paths bölümünden bir yol tablosu oluşturur ve gelen her isteği buna karşı eşleştirir.

Her yolun operationId değeri gönderim anahtarıdır. OnRequest içinde her işlemi sırayla işlersiniz:

uses
  sgcHTTP_OpenAPI_Server, sgcHTTP_OpenAPI_Server_Engine,
  sgcHTTPServer_OpenAPI;

procedure TForm1.OnOpenAPIRequest(Sender: TObject;
  const aOperationId: string; const aContext: TsgcOpenAPIServerContext;
  var Handled: Boolean);
begin
  Handled := True;
  if aOperationId = 'listPets' then
    HandleListPets(aContext)
  else if aOperationId = 'getPetById' then
    HandleGetPetById(aContext)
  else if aOperationId = 'createPet' then
    HandleCreatePet(aContext)
  else
    Handled := False;
end;

procedure TForm1.HandleGetPetById(const aContext: TsgcOpenAPIServerContext);
var
  vId, vPetJSON: string;
begin
  vId := aContext.PathParamAsString('petId');
  vPetJSON := FPets.Values[vId];
  if vPetJSON <> '' then
    aContext.RespondJSON(200, vPetJSON)
  else
    aContext.RespondError(404, 'Not Found', 'Pet ' + vId + ' not found');
end;

TsgcOpenAPIServerContext, istekteki her şey için türlenmiş erişimciler sağlar: şablonlanmış segmentler için PathParamAsString / PathParamAsInteger, varsayılan değerlerle QueryParamAsString / QueryParamAsInteger / QueryParamAsBoolean, istek gövdesi için BodyAsString / BodyAsJSON ve gelen herhangi bir başlık için HeaderValue. Yanıt vermek için RespondJSON(code, content) ve RespondError(code, title, detail) yardımcılarını kullanın veya tam denetim için Response.Code, Response.ContentType ve Response.Content değerlerini doğrudan ayarlayın.

Code-First — spec'i bir Delphi sınıfından üretme

API sözleşmesini Delphi'de yazmayı ve spec'in üretilmesini tercih ediyorsanız, bir sınıfı RTTI öznitelikleriyle donatın. TsgcOpenAPICodeFirstScanner sınıfı tarar, eksiksiz bir OpenAPI 3.0 JSON belgesi oluşturur ve siz bunu LoadFromString ile sunucuya yüklersiniz. Bu, Delphi XE7 veya daha yenisini gerektirir (genişletilmiş RTTI için).

uses
  sgcHTTP_OpenAPI_Server_CodeFirst;

type
  [sgcServiceContract('Task Manager API',
    'A simple task management demo', '1.0.0')]
  [sgcRoute('/api/v1')]
  TTaskManagerService = class
  public
    [sgcHttpGet]
    [sgcRoute('/tasks')]
    [sgcSummary('List all tasks')]
    [sgcTag('Tasks')]
    [sgcResponse(200, 'A list of tasks')]
    procedure ListTasks([sgcFromQuery] const status: string); virtual;

    [sgcHttpPost]
    [sgcRoute('/tasks')]
    [sgcSummary('Create a new task')]
    [sgcTag('Tasks')]
    [sgcResponse(201, 'Task created successfully')]
    procedure CreateTask([sgcFromBody] const body: string); virtual;

    [sgcHttpGet]
    [sgcRoute('/tasks/{taskId}')]
    [sgcSummary('Get a task by ID')]
    [sgcTag('Tasks')]
    [sgcResponse(200, 'The requested task')]
    [sgcResponse(404, 'Task not found')]
    procedure GetTask([sgcFromPath][sgcRequired]
      const taskId: Integer); virtual;
  end;

Metot gövdeleri saplamadır; yalnızca derleyicinin onlar için RTTI üretmesi amacıyla vardır. Asıl iş, tarayıcının her metot adından türettiği operationId (ListTasks, CreateTask, GetTask…) tarafından gönderilen OnRequest içinde gerçekleşir.

Başlangıçta sınıfı tarayıcıya verin ve üretilen spec'i sunucuya yükleyin:

uses
  sgcHTTP_OpenAPI_Server_CodeFirst, sgcHTTPServer_OpenAPI;

var
  oScanner: TsgcOpenAPICodeFirstScanner;
  oServer: TsgcHTTPServer_OpenAPI;
  vSpec: string;
begin
  oScanner := TsgcOpenAPICodeFirstScanner.Create;
  try
    vSpec := oScanner.GenerateSpec(TTaskManagerService);
  finally
    oScanner.Free;
  end;

  oServer := TsgcHTTPServer_OpenAPI.Create(nil);
  oServer.LoadFromString(vSpec);
  oServer.Bindings.Add.Port := 8081;
  oServer.OnRequest := MyOnRequest;
  oServer.Active := True;
end;

Öznitelikler yaygın meta verileri kapsar: sgcServiceContract OpenAPI info bloğunu doldurur, sgcRoute yolu sınıf veya metot düzeyinde ayarlar, sgcHttpGet / Post / Put / Delete / Patch / Head / Options fiili seçer, sgcSummary ve sgcDescription işlemi belgeler, sgcTag onu Swagger UI'de gruplar, sgcResponse(code, description) her yanıtı bildirir ve sgcRequired ile birlikte sgcFromPath / FromQuery / FromBody / FromHeader her parametreyi açıklar.

Yapılandırma — OpenAPIOptions

Tüm sunucu tarafı yapılandırması, üç alt seçenekte gruplandırılmış olarak OpenAPIOptions altında bulunur:

oServer.OpenAPIOptions.Endpoint.BasePath        := '/api';
oServer.OpenAPIOptions.Endpoint.ServeSpec       := True;   // /openapi.json
oServer.OpenAPIOptions.Endpoint.ServeSwaggerUI  := True;   // /docs

oServer.OpenAPIOptions.CORS.Enabled             := True;
oServer.OpenAPIOptions.CORS.AllowOrigins        := '*';
oServer.OpenAPIOptions.CORS.AllowHeaders        := 'Content-Type, Authorization';
oServer.OpenAPIOptions.CORS.AllowMethods        := 'GET, POST, PUT, DELETE, PATCH, OPTIONS';

oServer.OpenAPIOptions.Validation.ValidateRequest     := True;
oServer.OpenAPIOptions.Validation.ValidateRequestBody := True;
oServer.OpenAPIOptions.Validation.ValidateQueryParams := True;
oServer.OpenAPIOptions.Validation.ValidatePathParams  := True;
oServer.OpenAPIOptions.Validation.ValidateRequired    := True;

Doğrulama açıkken, gelen her istek işleyicinize ulaşmadan önce spec'te bildirilen JSON Şemalarına karşı denetlenir: zorunlu alanlar, türler, biçimler, enum'lar, aralıklar. Başarısızlıklar, hata listesi ve isteği kabul etmek veya reddetmek için bir bayrakla OnValidationError olayını tetikler.

Olaylar

Bileşen, istek yaşam döngüsü için altı olay sunar:

OnBeforeRequest: gönderimden önce tetiklenir; 403 Forbidden ile reddetmek için Accept := False ayarlayın. Hız sınırlama, günlüğe kaydetme veya yol başına geçitler için kullanışlıdır.

OnAuthenticate: ana işleyiciden önce tetiklenir; 401 Unauthorized ile reddetmek için Authenticated := False ayarlayın. Karar vermek için başlıkları, çerezleri veya sorgu parametrelerini inceleyin.

OnValidationError: doğrulama başarısız olduğunda tetiklenir; hata listesini alır. 400 Bad Request ile reddetmek için Continue := False ayarlayın.

OnRequest: ana gönderim olayı. aOperationId değerine bakın, yanıtı aContext.Response içine yazın, Handled := True ayarlayın.

OnAfterRequest: işleyici döndükten sonra tetiklenir; metrikler veya denetim günlüğü için idealdir.

OnException: işleyicinizden işlenmeyen bir özel durum çıkarsa tetiklenir. 500 Internal Server Error dışında bir şey istiyorsanız aResponseCode değerini ayarlayın.

Demolar

sgcOpenAPI 2026.6 ile iki eksiksiz demo gelir; her ikisi de yalnızca yeni bağımsız bileşeni kullanır ve sgcWebSockets kurulumu gerektirmez:

Yükseltme

Şu anda sgcWebSockets ile TsgcWSServer_API_OpenAPI kullanıyorsanız hiçbir şey değişmez; sınıf, özellikler ve olayların tümü korunur ve uygulama artık yeni bağımsız bileşeni çalıştıran aynı paylaşılan motora devreder. Mevcut kodunuzu olduğu gibi tutabilir veya sgcWebSockets bağımlılığını kaldırmak için her seferinde bir formu TsgcHTTPServer_OpenAPI bileşenine geçirebilirsiniz.

sgcOpenAPI 2026.6, Haziran ayında indirmeler sayfasında kullanıma sunulacak.

Sorularınız, geri bildiriminiz veya geçiş yardımı mı gerekiyor? Bize ulaşın — kodu yazan kişilerden bir yanıt alacaksınız.