De volgende release van sgcOpenAPI — versie 2026.6, verwacht in juni — bevat een gloednieuwe component: TsgcHTTPServer_OpenAPI. Het is één zelfstandige Delphi-component die een OpenAPI 3.0-service host met een ingebouwde HTTP-server. Plaats het op een formulier, wijs het naar een spec (of genereer er een uit een Delphi-klasse met RTTI-attributen), stel Active := True in, en je hebt een gedocumenteerde REST API met automatisch geserveerde Swagger UI.
De belangrijkste wijziging is dat sgcOpenAPI geen sgcWebSockets meer nodig heeft om een HTTP-server te hosten. De nieuwe component wordt volledig vanuit sgcOpenAPI geleverd, verpakt en geïnstalleerd. Als je sgcWebSockets al gebruikt, blijft de bestaande TsgcWSServer_API_OpenAPI-component ongewijzigd werken — beide delen intern dezelfde engine.
Wat je krijgt in één component
TsgcHTTPServer_OpenAPI bundelt drie zaken:
- Een ingebouwde HTTP-server (gebaseerd op Indy) met de gebruikelijke
Bindings-,Port- enActive-eigenschappen. - De OpenAPI-engine: spec-parsing, path-template-routing met
{paramName}-segmenten, JSON-Schema-validatie, CORS, afhandeling van uitzonderingen. - Twee automatisch geserveerde endpoints: de spec op
/openapi.jsonen een Swagger UI op/docs. Beide staan standaard aan en kunnen worden in- of uitgeschakeld inOpenAPIOptions.Endpoint.
Snelstart — het minimale voorbeeld
Dit is alles wat je nodig hebt om een werkende OpenAPI-server met Swagger UI te hosten:
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;
Navigeer naar http://localhost:8080/docs voor de Swagger UI en http://localhost:8080/openapi.json voor de spec. Elke operatie die in de spec is gedefinieerd, wordt naar je MyOnRequest-handler gerouteerd met het opgeloste operationId en een volledig opgebouwde request-context.
Spec-First — laad een bestaand OpenAPI 3.0-bestand
Als je al een OpenAPI 3.0 JSON- of YAML-bestand hebt (Petstore, een intern API-contract, een openbaar schema dat je wilt mocken), is spec-first de snelste manier om het te serveren. LoadFromFile leest en parseert de spec, bouwt een routetabel op uit de paths-sectie, en matcht elk binnenkomend verzoek daartegen.
Het operationId van elke route is de dispatch-sleutel. Binnen OnRequest handel je elke operatie achtereenvolgens af:
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;
De TsgcOpenAPIServerContext geeft je getypeerde accessors voor alles in het verzoek: PathParamAsString / PathParamAsInteger voor template-segmenten, QueryParamAsString / QueryParamAsInteger / QueryParamAsBoolean met standaardwaarden, BodyAsString / BodyAsJSON voor de request-body, en HeaderValue voor elke binnenkomende header. Om te antwoorden gebruik je de helpers RespondJSON(code, content) en RespondError(code, title, detail), of stel je Response.Code, Response.ContentType en Response.Content rechtstreeks in voor volledige controle.
Code-First — genereer de spec uit een Delphi-klasse
Als je het API-contract liever in Delphi schrijft en de spec laat genereren, voorzie je een klasse van RTTI-attributen. TsgcOpenAPICodeFirstScanner doorloopt de klasse, bouwt een compleet OpenAPI 3.0 JSON-document op, en dat laad je in de server met LoadFromString. Dit vereist Delphi XE7 of nieuwer (voor uitgebreide RTTI).
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;
De methode-bodies zijn stubs — ze bestaan alleen zodat de compiler er RTTI voor genereert. Het echte werk gebeurt in OnRequest, gedispatched door het operationId dat de scanner afleidt uit elke methodenaam (ListTasks, CreateTask, GetTask…).
Geef de klasse bij het opstarten aan de scanner en laad de gegenereerde spec in de server:
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;
De attributen dekken de meest voorkomende metadata: sgcServiceContract vult het OpenAPI info-blok, sgcRoute stelt het pad in op klasse- of methodeniveau, sgcHttpGet / Post / Put / Delete / Patch / Head / Options kiest het werkwoord, sgcSummary en sgcDescription documenteren de operatie, sgcTag groepeert deze in Swagger UI, sgcResponse(code, description) declareert elk antwoord, en sgcFromPath / FromQuery / FromBody / FromHeader samen met sgcRequired beschrijven elke parameter.
Configuratie — OpenAPIOptions
Alle server-side configuratie zit onder OpenAPIOptions, gegroepeerd in drie sub-opties:
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;
Met validatie ingeschakeld wordt elk binnenkomend verzoek gecontroleerd aan de hand van de JSON-Schemas die in de spec zijn gedeclareerd voordat het je handler bereikt — verplichte velden, types, formaten, enums, bereiken. Mislukkingen activeren de OnValidationError-event met de lijst met fouten en een vlag om het verzoek te accepteren of te weigeren.
Events
De component biedt zes events voor de request-levenscyclus:
OnBeforeRequest: wordt geactiveerd vóór dispatch; stel Accept := False in om te weigeren met een 403 Forbidden. Handig voor rate-limiting, logging of per-route-gates.
OnAuthenticate: wordt geactiveerd vóór de hoofdhandler; stel Authenticated := False in om te weigeren met 401 Unauthorized. Inspecteer headers, cookies of query-parameters om te beslissen.
OnValidationError: wordt geactiveerd wanneer validatie mislukt; ontvangt de lijst met fouten. Stel Continue := False in om te weigeren met 400 Bad Request.
OnRequest: de hoofd-dispatch-event. Bekijk aOperationId, schrijf het antwoord in aContext.Response, stel Handled := True in.
OnAfterRequest: wordt geactiveerd nadat de handler is teruggekeerd — ideaal voor metrics of audit-logging.
OnException: wordt geactiveerd als een onafgehandelde uitzondering uit je handler komt. Pas aResponseCode aan als je iets anders wilt dan 500 Internal Server Error.
Demo's
Twee complete demo's worden met sgcOpenAPI 2026.6 meegeleverd, beide met uitsluitend de nieuwe standalone component — geen sgcWebSockets-installatie vereist:
- Demos/30.Server/01.CodeFirst — een Task Manager API die volledig is gedefinieerd met attributen op een Delphi-klasse.
- Demos/30.Server/02.SpecFirst — het klassieke Petstore-voorbeeld, geserveerd vanuit
petstore.json.
Upgraden
Als je momenteel TsgcWSServer_API_OpenAPI met sgcWebSockets gebruikt, verandert er niets — de klasse, eigenschappen en events blijven allemaal behouden en de implementatie delegeert nu naar dezelfde gedeelde engine die de nieuwe standalone component aandrijft. Je kunt je bestaande code zo laten, of formulier voor formulier migreren naar TsgcHTTPServer_OpenAPI om de sgcWebSockets-afhankelijkheid te verwijderen.
sgcOpenAPI 2026.6 zal in juni beschikbaar zijn op de downloadpagina.
Vragen, feedback of hulp bij migratie? Neem contact op — je krijgt antwoord van de mensen die de code hebben geschreven.
