sgcWebSockets Enterprise sürümü, bir OpenAPI 3 açıklamasını Delphi uygulamanızın içinde çalışan bir REST sunucusuna dönüştüren yeni bir bileşen, TsgcWSAPIServer_OpenAPI ile gelir. Onu bir forma bırakın, bir HTTP sunucusuna yönlendirin, ona bir spesifikasyon verin — ve rotalar, istek doğrulama, hata yanıtları ve canlı Swagger UI belgeleri sizin için bağlanır. Bu yazı, bileşenin nasıl çalıştığını, onu sürmenizin iki yolunu (spesifikasyon-önce ve kod-önce), önemli yapılandırma ayarlarını ve doğrudan yeni bir projeye yapıştırabileceğiniz tam bir Delphi örneğini adım adım anlatır.
Bileşen ne yapar
TsgcWSAPIServer_OpenAPI, mevcut API-sunucusu uzantı noktası aracılığıyla TsgcWebSocketHTTPServer'a bağlanan ince bir API sunucusudur. Onu bir sunucuya iliştirir, bir OpenAPI 3.0 spesifikasyonu yükler ve gelen her HTTP isteğinde dört şey yapar:
- URL'yi ve HTTP metodunu, spesifikasyonda bildirilen rotalarla (
{path}parametreleri dahil) eşleştirir; - isteği (zorunlu alanlar, query parametreleri, path parametreleri ve istek gövdesi) spesifikasyondaki şemalara karşı doğrular;
- çözülmüş
operationIdve tamamen doldurulmuş bir bağlam nesnesiyle birOnRequestolayı tetikler, böylece kodunuzun yalnızca iş mantığı yazması gerekir; - kutudan çıkar çıkmaz iki yerleşik uç nokta sunar —
/openapi.json'da ham spesifikasyon ve/docs'ta etkileşimli bir Swagger UI — her rotada isteğe bağlı CORS ön kontrolüyle.
Sonuç, spesifikasyonun tek doğru kaynağı haline gelmesidir: JSON'da bir yol, bir parametre veya bir yanıt kodu değiştirin, yeniden başlatın ve sunucu Delphi kodunu yeniden derlemeden yeni sözleşmeyi alır.
Spesifikasyon-önce: mevcut bir OpenAPI 3 dosyası yükleyin
Zaten bir OpenAPI 3 belgeniz varsa (örneğin bir API tasarımcısından dışa aktarılmış bir petstore.json) bağlama esasen üç satırdır — bileşeni oluşturun, spesifikasyonu yükleyin, bir sunucu iliştirin. Geri kalan her şey yapılandırma ve gerçek yanıtları üreten OnRequest işleyicisidir.
uses
sgcWebSocket, sgcWebSocket_Classes,
sgcWebSocket_Server_API_OpenAPI,
sgcHTTP_OpenAPI_Server;
var
WSServer: TsgcWebSocketHTTPServer;
FOpenAPI: TsgcWSAPIServer_OpenAPI;
begin
WSServer := TsgcWebSocketHTTPServer.Create(nil);
WSServer.Port := 8080;
FOpenAPI := TsgcWSAPIServer_OpenAPI.Create(nil);
FOpenAPI.OnRequest := OnOpenAPIRequest;
FOpenAPI.OnBeforeRequest := OnOpenAPIBeforeRequest;
FOpenAPI.OnValidationError := OnOpenAPIValidationError;
// Configuration
FOpenAPI.OpenAPIOptions.Endpoint.ServeSpec := True;
FOpenAPI.OpenAPIOptions.Endpoint.ServeSwaggerUI := True;
FOpenAPI.OpenAPIOptions.CORS.Enabled := True;
FOpenAPI.OpenAPIOptions.Validation.ValidateRequest := True;
FOpenAPI.OpenAPIOptions.Validation.ValidateRequired := True;
FOpenAPI.OpenAPIOptions.Validation.ValidateRequestBody := True;
// Load spec and attach to server
FOpenAPI.LoadFromFile('petstore.json');
FOpenAPI.Server := WSServer;
WSServer.Active := True;
// Swagger UI: http://localhost:8080/docs
// Raw spec: http://localhost:8080/openapi.json
end;
OnRequest olayı operationId başına gönderilir — YAML/JSON'da her işlemin yanına yazdığınız dize. İşlem başına bir dal yazar, girdileri bağlamdan okur ve bir yanıt yayarsınız:
procedure TForm1.OnOpenAPIRequest(Sender: TObject;
const aOperationId: string; const aContext: TsgcOpenAPIServerContext;
var Handled: Boolean);
var
vId: Int64;
vLimit: Integer;
begin
Handled := True;
if aOperationId = 'listPets' then
begin
vLimit := aContext.QueryParamAsInteger('limit', 100);
aContext.RespondJSON(200, BuildPetsJSON(vLimit));
end
else if aOperationId = 'getPetById' then
begin
vId := aContext.PathParamAsInteger('petId');
if FindPet(vId) then
aContext.RespondJSON(200, PetAsJSON(vId))
else
aContext.RespondError(404, 'Not Found',
Format('Pet %d not found', [vId]));
end
else
Handled := False;
end;
TsgcOpenAPIServerContext nesnesi, her işleyicinin işçi atıdır. Path ve query parametrelerini ada göre (PathParamAsString, PathParamAsInteger, QueryParamAsString, QueryParamAsInteger, QueryParamAsBoolean), HeaderValue aracılığıyla başlık aramasını, gövdeyi bir dize (BodyAsString) veya önceden ayrıştırılmış JSON (BodyAsJSON) olarak ve ayrıca iki yanıt yardımcısını açığa çıkarır: normal bir yük için RespondJSON(code, content) ve istemcilerin her zaman tutarlı bir hata biçimi alması için RFC 7807 tarzında bir application/problem+json gövdesi üreten RespondError(code, title, detail).
Kod-önce: spesifikasyonu Delphi öznitelilerinden oluşturun
İkinci mod ters akıştır: API'nizi öznitelilerle süslenmiş bir Delphi sınıfı olarak bildirir, tarayıcıdan çalışma zamanında OpenAPI belgesini yaymasını ister ve o belgeyi aynı bileşene geri beslersiniz. JSON'da elle yazılacak bir şey yoktur.
uses
sgcHTTP_OpenAPI_Server_CodeFirst;
type
[sgcServiceContract('Task Manager API',
'A simple task manager', '1.0.0')]
[sgcRoute('/api/v1')]
TTaskService = class
public
[sgcHttpGet]
[sgcRoute('/tasks')]
[sgcSummary('List all tasks')]
[sgcResponse(200, 'A list of tasks')]
procedure ListTasks([sgcFromQuery] const status: string); virtual;
[sgcHttpGet]
[sgcRoute('/tasks/{taskId}')]
[sgcSummary('Get a task by ID')]
[sgcResponse(200, 'The requested task')]
[sgcResponse(404, 'Task not found')]
procedure GetTask([sgcFromPath][sgcRequired]
const taskId: Integer); virtual;
[sgcHttpPost]
[sgcRoute('/tasks')]
[sgcSummary('Create a new task')]
[sgcResponse(201, 'Task created')]
procedure CreateTask([sgcFromBody] const body: string); virtual;
end;
Sınıfın kendisinin gerçek gövdelere ihtiyacı yoktur — tarayıcı onu RTTI aracılığıyla okur, gerçek mantık hâlâ OnRequest işleyicinizde bulunur. Spesifikasyonu oluşturmak ve sunucuyu başlatmak birkaç satırdır:
var
oScanner: TsgcOpenAPICodeFirstScanner;
vSpec: string;
begin
oScanner := TsgcOpenAPICodeFirstScanner.Create;
try
vSpec := oScanner.GenerateSpec(TTaskService);
finally
oScanner.Free;
end;
FOpenAPI.LoadFromString(vSpec);
FOpenAPI.Server := WSServer;
WSServer.Active := True;
end;
Öznitelik seti yaygın durumları kapsar: yönlendirme (sgcHttpGet, sgcHttpPost, sgcHttpPut, sgcHttpDelete, sgcHttpPatch, sgcRoute), parametre bağlama (sgcFromPath, sgcFromQuery, sgcFromHeader, sgcFromBody), doğrulama (sgcRequired, sgcMinLength, sgcMaxLength, sgcRange, sgcPattern) ve belgeleme (sgcSummary, sgcDescription, sgcTag, sgcResponse).
Yapılandırma ayrıntılı olarak
OpenAPIOptions, hepsini Object Inspector'da görebilmeniz için üç kalıcı alt nesneye gruplandırılmıştır:
Endpoint—BasePath, her rotanın ve yerleşik/openapi.jsonile/docsuç noktalarının önüne bir önek ekler;SpecFile,LoadFromFile'a alternatif olarak tasarım zamanında kullanılabilir;ServeSpecveServeSwaggerUI, iki yerleşik uç noktayı açar/kapatır (her ikisi de varsayılan olarak açıktır).Validation— ana anahtarValidateRequest'tir;ValidateRequired,ValidateQueryParams,ValidatePathParamsveValidateRequestBody, neyin kontrol edileceğini daraltmanıza olanak tanır. Doğrulama başarısız olduğunda,OnValidationError, sorunların listesi ve birContinuebayrağıyla tetiklenir — isteği otomatik olarak reddetmek için onuFalseolarak ayarlayın.CORS—Enabled := Trueayarlayın, sunucu, yanıt politikası olarakAllowOrigins,AllowHeadersveAllowMethodskullanarak her rota için ön kontrolOPTIONSisteklerini yanıtlar.
OnRequest'in ötesinde, dört olay daha boru hattına müdahale etmenize olanak tanır: OnBeforeRequest (kısa devre yapmak için Accept := False ayarlayın, hız sınırlama veya günlük kaydı için kullanışlı), OnAfterRequest (bir yanıt ürettikten sonra son işleme), OnAuthenticate (bir token veya oturumu kontrol ettikten sonra Authenticated := True ayarlayın) ve OnException (çerçeve hata gövdesini yazmadan önce HTTP durumunu değiştirmenize olanak tanıyan her şeyi yakalayan).
Kutudan çıkar çıkmaz Swagger UI
ServeSwaggerUI := True ile sunucu, spesifikasyonu BasePath + '/openapi.json''dan yükleyen bir Swagger UI sayfasını BasePath + '/docs''ta yayımlar. URL'yi bir tarayıcıda açın ve kendi çalışan sunucunuzdan beslenen standart dene-bunu deneyimini elde edin — ayrı bir belge derlemesi yok, statik dışa aktarma yok. CORS ile birleştirildiğinde, bu, bir arka ucu (backend) bir ön uç (frontend) ekibine veya API'nize karşı entegre olan bir ortağa teslim etmenin en hızlı yoludur.
Edinme
Bileşen, sgcWebSockets'in Enterprise sürümünün bir parçasıdır ve SGC OpenAPI palet sayfasında kayıtlıdır. İki tam demo — biri bir Petstore JSON kullanan spesifikasyon-önce, biri bir görev yöneticisi hizmeti kullanan kod-önce — Demos\23.OpenAPI içinde gelir. En son derlemeyi sgcWebSockets indirme sayfasından indirin.
Sorular, geri bildirim veya onu mevcut bir projeye bağlama konusunda yardım mı? Bize ulaşın — kodu yazan kişilerden bir yanıt alacaksınız.
