La prochaine version de sgcOpenAPI — la version 2026.6, prévue pour juin — livre un tout nouveau composant : TsgcHTTPServer_OpenAPI. Il s'agit d'un unique composant Delphi autonome qui héberge un service OpenAPI 3.0 avec un serveur HTTP embarqué. Posez-le sur une fiche, pointez-le vers une spécification (ou générez-en une à partir d'une classe Delphi avec des attributs RTTI), définissez Active := True, et vous obtenez une API REST documentée avec Swagger UI servi automatiquement.
Le changement principal est que sgcOpenAPI n'a plus besoin de sgcWebSockets pour héberger un serveur HTTP. Le nouveau composant est livré, packagé et installé entièrement depuis sgcOpenAPI. Si vous utilisez déjà sgcWebSockets, l'ancien composant TsgcWSServer_API_OpenAPI continue de fonctionner sans changement — les deux partagent le même moteur en interne.
Ce que vous obtenez dans un seul composant
TsgcHTTPServer_OpenAPI regroupe trois éléments :
- Un serveur HTTP embarqué (basé sur Indy) avec les propriétés habituelles
Bindings,PortetActive. - Le moteur OpenAPI : analyse de la spécification, routage par modèle de chemin avec des segments
{paramName}, validation JSON-Schema, CORS, gestion des exceptions. - Deux points de terminaison servis automatiquement : la spécification sur
/openapi.jsonet un Swagger UI sur/docs. Les deux sont activés par défaut et peuvent être basculés dansOpenAPIOptions.Endpoint.
Démarrage rapide — l'exemple minimal
Voici tout ce dont vous avez besoin pour héberger un serveur OpenAPI fonctionnel avec Swagger UI :
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;
Naviguez vers http://localhost:8080/docs pour le Swagger UI et http://localhost:8080/openapi.json pour la spécification. Chaque opération définie dans la spécification est routée vers votre gestionnaire MyOnRequest avec l'operationId résolu et un contexte de requête entièrement construit.
Spec-First — charger un fichier OpenAPI 3.0 existant
Si vous avez déjà un fichier OpenAPI 3.0 au format JSON ou YAML (Petstore, un contrat d'API interne, un schéma public que vous souhaitez simuler), la méthode spec-first est la plus rapide pour le servir. LoadFromFile lit et analyse la spécification, construit une table de routage à partir de la section paths, et fait correspondre chaque requête entrante à celle-ci.
L'operationId de chaque route est la clé de dispatch. À l'intérieur de OnRequest, vous traitez chaque opération tour à tour :
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;
Le TsgcOpenAPIServerContext vous donne des accesseurs typés pour tout ce qui se trouve dans la requête : PathParamAsString / PathParamAsInteger pour les segments à modèle, QueryParamAsString / QueryParamAsInteger / QueryParamAsBoolean avec des valeurs par défaut, BodyAsString / BodyAsJSON pour le corps de la requête, et HeaderValue pour tout en-tête entrant. Pour répondre, utilisez les helpers RespondJSON(code, content) et RespondError(code, title, detail), ou définissez directement Response.Code, Response.ContentType et Response.Content pour un contrôle complet.
Code-First — générer la spécification à partir d'une classe Delphi
Si vous préférez écrire le contrat d'API en Delphi et laisser la spécification être générée, décorez une classe avec des attributs RTTI. TsgcOpenAPICodeFirstScanner parcourt la classe, construit un document JSON OpenAPI 3.0 complet, et vous le chargez dans le serveur avec LoadFromString. Cela nécessite Delphi XE7 ou plus récent (pour le RTTI étendu).
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;
Les corps des méthodes sont des stubs — ils n'existent que pour que le compilateur émette le RTTI correspondant. Le vrai travail se fait dans OnRequest, dispatché par l'operationId que le scanner dérive de chaque nom de méthode (ListTasks, CreateTask, GetTask…).
Transmettez la classe au scanner au démarrage et chargez la spécification générée dans le serveur :
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;
Les attributs couvrent les métadonnées courantes : sgcServiceContract remplit le bloc info d'OpenAPI, sgcRoute définit le chemin au niveau de la classe ou de la méthode, sgcHttpGet / Post / Put / Delete / Patch / Head / Options choisit le verbe, sgcSummary et sgcDescription documentent l'opération, sgcTag la regroupe dans Swagger UI, sgcResponse(code, description) déclare chaque réponse, et sgcFromPath / FromQuery / FromBody / FromHeader avec sgcRequired décrivent chaque paramètre.
Configuration — OpenAPIOptions
Toute la configuration côté serveur se trouve sous OpenAPIOptions, regroupée en trois sous-options :
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;
Avec la validation activée, chaque requête entrante est vérifiée par rapport aux schémas JSON déclarés dans la spécification avant d'atteindre votre gestionnaire — champs obligatoires, types, formats, énumérations, plages de valeurs. Les échecs déclenchent l'événement OnValidationError avec la liste des erreurs et un indicateur pour accepter ou rejeter la requête.
Événements
Le composant expose six événements pour le cycle de vie de la requête :
OnBeforeRequest : se déclenche avant le dispatch ; définissez Accept := False pour rejeter avec un 403 Forbidden. Utile pour la limitation de débit, la journalisation ou les contrôles par route.
OnAuthenticate : se déclenche avant le gestionnaire principal ; définissez Authenticated := False pour rejeter avec 401 Unauthorized. Inspectez les en-têtes, les cookies ou les paramètres de requête pour décider.
OnValidationError : se déclenche lorsque la validation échoue ; reçoit la liste des erreurs. Définissez Continue := False pour rejeter avec 400 Bad Request.
OnRequest : l'événement principal de dispatch. Regardez aOperationId, écrivez la réponse dans aContext.Response, définissez Handled := True.
OnAfterRequest : se déclenche après le retour du gestionnaire — idéal pour les métriques ou la journalisation d'audit.
OnException : se déclenche si une exception non gérée remonte depuis votre gestionnaire. Ajustez aResponseCode si vous souhaitez autre chose que 500 Internal Server Error.
Démos
Deux démos complètes sont livrées avec sgcOpenAPI 2026.6, toutes deux utilisant uniquement le nouveau composant autonome — aucune installation de sgcWebSockets requise :
- Demos/30.Server/01.CodeFirst — une API Task Manager définie entièrement avec des attributs sur une classe Delphi.
- Demos/30.Server/02.SpecFirst — l'exemple classique Petstore, servi depuis
petstore.json.
Mise à niveau
Si vous utilisez actuellement TsgcWSServer_API_OpenAPI avec sgcWebSockets, rien ne change — la classe, les propriétés et les événements sont tous préservés et l'implémentation délègue désormais au même moteur partagé qui alimente le nouveau composant autonome. Vous pouvez conserver votre code existant tel quel, ou migrer une fiche à la fois vers TsgcHTTPServer_OpenAPI pour supprimer la dépendance à sgcWebSockets.
sgcOpenAPI 2026.6 sera disponible sur la page de téléchargements en juin.
Questions, retours ou aide à la migration ? Contactez-nous — vous obtiendrez une réponse des personnes qui ont écrit le code.
