Serveur OpenAPI pour Delphi

TsgcWSAPIServer_OpenAPI sert le document OpenAPI 3.x que vous chargez, fait correspondre chaque requête entrante à ce document, valide la requête avant que votre handler ne s'exécute, et publie le document ainsi qu'une page Swagger UI depuis le même port. Un seul composant Delphi, attaché à un TsgcHTTPServer.

OpenAPI 3.0 et 3.1
HTTP/2 + TLS 1.3
Swagger UI sur /docs
Spec-first ou Code-first

TsgcWSAPIServer_OpenAPI

Un seul composant Delphi qui transforme un document OpenAPI en serveur REST fonctionnel, validé et auto-documenté.

Classe du composant

TsgcWSAPIServer_OpenAPI, déclarée dans sgcWebSocket_Server_API_OpenAPI

Serveur hôte

Affectez à Server un TsgcHTTPServer, un TsgcHTTPRESTServer ou un TsgcWebSocketHTTPServer. L'hôte possède le port, les bindings et le TLS.

Format de spec

Documents OpenAPI 3.0 et 3.1, lus en JSON par LoadFromFile et LoadFromString

Deux workflows

Spec-first à partir d'un document que vous avez déjà, ou code-first à partir d'une classe Delphi annotée. Le code-first nécessite Delphi XE7 ou plus récent.

Édition

Livré avec sgcOpenAPI. Dans sgcWebSockets, il appartient à l'édition Enterprise, sur la page de palette SGC OpenAPI.

Points de terminaison intégrés

/openapi.json pour le document et /docs pour Swagger UI, tous deux activés dans OpenAPIOptions.Endpoint

Spec-first ou Code-first, à vous de choisir

Le même composant fonctionne dans les deux modes. Partez d'un contrat JSON, ou décrivez l'API en Delphi et laissez le scanner générer le document pour vous.

1. Spec-first

Chargez petstore.json avec LoadFromFile, dispatchez sur l'operation id à l'intérieur de OnRequest, et lancez le serveur. Le routage, le binding des paramètres de path et de query, et la validation viennent tous du contrat, si bien que vous n'écrivez que la logique métier.

Idéal pour : les équipes avec un contrat de design partagé, l'intégration API-led ou les back-ends polyglottes où la spec fait foi.

2. Code-first

Annotez une simple classe Delphi avec sgcServiceContract, sgcRoute, sgcHttpGet et les attributs de paramètre sgcFromPath / sgcFromQuery / sgcFromBody. TsgcOpenAPICodeFirstScanner.GenerateSpec construit le document OpenAPI à partir de la RTTI de la classe, vous le transmettez à LoadFromString, et le même endpoint /openapi.json le publie.

Idéal pour : le prototypage rapide, les services internes ou le portage d'une surface REST TIdHTTPServer / DataSnap existante vers une API auto-documentée.

Un serveur opérationnel en 20 lignes

Créez le composant, chargez un document, attachez-le à un serveur HTTP. C'est toute la configuration.

Delphi
uses
  sgcHTTP_Server, sgcHTTP_OpenAPI_Server, sgcWebSocket_Server_API_OpenAPI;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FServer := TsgcHTTPServer.Create(Self);
  FServer.Port := 8080;

  FOpenAPI := TsgcWSAPIServer_OpenAPI.Create(Self);
  FOpenAPI.LoadFromFile('petstore.json');      // any OpenAPI 3.x document
  FOpenAPI.OpenAPIOptions.Endpoint.ServeSpec := True;
  FOpenAPI.OpenAPIOptions.Endpoint.ServeSwaggerUI := True;
  FOpenAPI.OnRequest := OpenAPIRequest;
  FOpenAPI.Server := FServer;                // Server is the switch, there is no Active

  FServer.Active := True;
end;

// one event, dispatched by operation id
procedure TForm1.OpenAPIRequest(Sender: TObject;
  const aOperationId: string;
  const aContext: TsgcOpenAPIServerContext;
  var Handled: Boolean);
begin
  Handled := True;
  if aOperationId = 'getPetById' then
    aContext.RespondJSON(200, FPets.Values[aContext.PathParamAsString('petId')])
  else
    Handled := False;
end;

Ce que vous obtenez d'emblée : GET /pets/{petId} atteint le handler ci-dessus avec aOperationId à getPetById, GET /openapi.json renvoie le document que vous avez chargé, GET /docs ouvre Swagger UI. OpenAPIOptions.Endpoint.BasePath déplace toute la surface sous un préfixe, et TLS et HTTP/2 viennent du serveur hôte.

Les paramètres déclarés dans le document OpenAPI sont lus et convertis via un unique contexte typé. Avec la validation activée, un type incorrect est signalé par 400 Bad Request avant que votre handler ne s'exécute.

Delphi
// spec snippet
//   /pets:
//     get:
//       operationId: listPets
//       parameters:
//         - name: limit       in: query    schema: { type: integer, maximum: 100 }
//         - name: status      in: query    schema: { type: string, enum: [available, pending, sold] }
//         - name: X-Tenant-Id in: header   required: true

procedure TForm1.HandleListPets(const aContext: TsgcOpenAPIServerContext);
var
  vLimit:  Integer;
  vStatus: string;
  vTenant: string;
begin
  vLimit  := aContext.QueryParamAsInteger('limit', 20);        // default 20
  vStatus := aContext.QueryParamAsString ('status', 'available');
  vTenant := aContext.HeaderValue        ('X-Tenant-Id');   // required in the spec

  aContext.RespondJSON(200, PetRepo.List(vTenant, vStatus, vLimit));
end;

Validation de schéma avant que votre handler ne s'exécute

Chaque requête entrante est vérifiée par rapport aux schémas déclarés dans le document. Un échec est signalé par un document de problème au format RFC 7807 listant chaque erreur, et n'atteint jamais votre handler sauf si vous le décidez.

Ce qui est vérifié

type, required, properties et additionalProperties, enum et const, minLength / maxLength, pattern, minimum / maximum avec leurs formes exclusives, multipleOf, items, minItems / maxItems, uniqueItems, nullable, not, et oneOf / anyOf / allOf. Le mot-clé format est appliqué pour date, date-time, email, ipv4, uri et uuid.

Choisissez la portée

Validation.ValidateRequest est l'interrupteur principal et valide à lui seul toutes les portées. Restreignez-le avec ValidateRequestBody, ValidateQueryParams, ValidatePathParams, ValidateHeaderParams et ValidateCookieParams. EnforceRequired reste actif quelle que soit la portée choisie.

Vous avez le dernier mot

OnValidationError vous transmet l'operation id et la liste complète des échecs. Son indicateur Continue arrive à False, si bien que la requête est rejetée à moins que vous ne le positionniez délibérément à True. Après un chargement, Validation.Warnings nomme chaque mot-clé de schéma que le document utilise et qui n'est pas appliqué, si bien qu'une liste vide signifie que rien n'est passé inaperçu.

JSON, le 400 émis par le moteur
{
  "type":   "about:blank",
  "title":  "Bad Request",
  "status": 400,
  "detail": "Request validation failed",
  "errors": [
    "/email: invalid email format",
    "/age: must be <= 120",
    "/status: value not in enum"
  ]
}

Schémas d'auth pilotés par la spec

Positionnez Security.EnforceSecurity et les securitySchemes déclarés par le document sont appliqués aux requêtes entrantes. Vous écrivez la recherche des identifiants, le composant analyse la requête et répond 401 ou 403 lorsque la recherche échoue.

API Key

Lue dans un en-tête, un paramètre de query ou un cookie, selon ce que déclare le schéma. OnValidateAPIKey reçoit le schéma, le nom, l'emplacement et la clé, et répond via Valid.

HTTP Basic

L'en-tête Authorization est analysé pour vous. OnValidateBasic reçoit l'utilisateur et le mot de passe et répond via Valid. Les identifiants ne sont jamais écrits dans le log.

Bearer et JWT

Security.JWTSecret vérifie le token. Un secret HMAC est utilisé tel quel, une valeur contenant -----BEGIN est traitée comme une clé publique PEM. ValidateExpiration, Issuer et Audience vérifient les claims.

Votre propre vérificateur

Laissez JWTSecret vide et le token n'est vérifié que pour sa présence, si bien que OnValidateBearer peut le transmettre à votre propre service de tokens et répondre via Valid.

401 ou 403

Une requête en échec reçoit 401, ou 403 lorsqu'elle s'est authentifiée mais a échoué seulement sur la portée. OnAuthenticate s'exécute en premier et rejette avec 401 dès que vous effacez Authenticated.

Mock avant que le code n'existe

Mock.Enabled répond à une opération sans handler à partir des exemples et schémas du document lui-même, avec Mock.StatusCode, pour qu'une équipe front-end puisse travailler pendant que l'implémentation s'écrit.

Delphi, token bearer vérifié par votre propre code
FOpenAPI.OpenAPIOptions.Security.EnforceSecurity := True;
FOpenAPI.OpenAPIOptions.Security.JWTSecret := GetSecretFromEnvironment;
FOpenAPI.OpenAPIOptions.Security.ValidateExpiration := True;
FOpenAPI.OpenAPIOptions.Security.Issuer   := 'https://auth.example.com';
FOpenAPI.OpenAPIOptions.Security.Audience := 'api.example.com';
FOpenAPI.OnValidateBearer := OpenAPIValidateBearer;

procedure TForm1.OpenAPIValidateBearer(Sender: TObject;
  const aToken: string;
  const aContext: TsgcOpenAPIServerContext; var Valid: Boolean);
begin
  Valid := MyTokenService.Verify(aToken);
end;

Swagger UI embarqué

Aucune dépendance externe, pas de Node.js, pas de build de documentation dans la pipeline de déploiement. Le composant écrit lui-même la page et lit le document que votre serveur sert réellement.

/openapi.json

Le document que vous avez chargé, servi lorsque Endpoint.ServeSpec est actif. Toujours en phase avec ce que le serveur route réellement. Pointez n'importe quel générateur de client sur cette URL, sgcOpenAPI compris.

/docs

La page Swagger UI interactive, servie lorsque Endpoint.ServeSwaggerUI est actif. Essayez les opérations, parcourez les schémas, lisez les exemples, le tout alimenté par votre propre serveur en cours d'exécution.

Épinglé, ou entièrement hors ligne

La page charge par défaut son CSS et son JavaScript depuis un CDN public. Endpoint.SwaggerUIBaseURL épingle une version, et Endpoint.SwaggerUIAssetsPath sert swagger-ui.css et swagger-ui-bundle.js depuis un dossier local, si bien qu'une machine air-gapée fonctionne aussi.

Tout se trouve sous OpenAPIOptions

Cinq sous-objets persistants, tous visibles dans l'Inspecteur d'objets, tous affectables à l'exécution.

Endpoint

BasePath préfixe chaque route et les deux endpoints intégrés. ServeSpec et ServeSwaggerUI les activent ou les désactivent. SpecFile est chargé paresseusement, à la première requête qui n'est ni l'un ni l'autre, utilisez donc LoadFromFile lorsque le document doit être complet dès le tout premier appel.

Validation

ValidateRequest plus les cinq interrupteurs de portée, et EnforceRequired. Warnings rapporte, après chaque chargement, les mots-clés de schéma que le document utilise et que ce validateur n'applique pas.

CORS

Enabled, AllowOrigins, AllowHeaders et AllowMethods. Le moteur appose les réponses sur les chemins que possède son document, donnez donc au serveur hôte les mêmes valeurs pour les chemins qu'il possède.

Security

EnforceSecurity, JWTSecret, ValidateExpiration, Issuer et Audience. Tout ce que les contrôles intégrés ne peuvent pas trancher atteint OnValidateAPIKey, OnValidateBasic ou OnValidateBearer.

Mock

Enabled et StatusCode. Une opération sans handler reçoit une réponse tirée des exemples et schémas du document lui-même, si bien que le contrat est appelable avant que l'implémentation n'existe.

Not Implemented, volontairement

Laissez Handled à False et le moteur répond 501 Not Implemented en nommant l'opération, plutôt qu'un 404 qui ressemblerait à une erreur de routage.

Un seul serveur HTTP, plusieurs surfaces

TsgcWSAPIServer_OpenAPI s'attache au même serveur HTTP sgcWebSockets qui héberge vos endpoints WebSocket, vos streams IA/LLM et vos fichiers statiques. Un port, un certificat TLS, un flux de logs.

Server est l'interrupteur

Il n'y a pas de propriété Active. Affecter Server attache le composant, le positionner à nil le détache, dans les deux cas pendant que le serveur hôte continue de tourner. Détaché, les chemins que possède son document retombent directement sur votre handler ordinaire.

Il ne s'approprie jamais le serveur

Chaque requête est d'abord proposée au composant, qui ne répond qu'aux chemins que déclare son document. Tout le reste atteint OnCommandGet comme avant, si bien qu'une section contract-first cohabite avec des routes écrites à la main et du contenu statique venant de DocumentRoot, le tout sur un seul port.

Le TLS et le HTTP/2 de l'hôte

Le port, les bindings, le certificat et la négociation HTTP/2 appartiennent au serveur hôte, si bien que la surface REST les hérite sans changement. Attachez-le à un TsgcHTTPRESTServer et le CORS, les métriques, la santé et le tenancy de ce serveur s'appliquent aussi.

Déploiements typiques

APIs REST publiques

Versionnées, testées par contrat, avec des SDK auto-générés que vos clients peuvent télécharger depuis /openapi.json.

Microservices internes

Contrats de service à service qui survivent aux refactorings — la spec est le test d'intégration.

Passerelles industrielles / IoT

Équipements edge exposant un plan de contrôle REST documenté plus une surface télémétrie MQTT ou WebSocket depuis le même binaire Delphi.

Récepteurs de webhooks

Chaque payload de webhook fournisseur devient un record Pascal typé — Stripe, GitHub, Twilio, Slack — avec validation et idempotence intégrées.

Modernisation de legacy

Enveloppez un vieux back-end DataSnap ou RemObjects derrière une surface OpenAPI propre sans réécrire la logique métier.

BFF (Backend-for-Frontend)

Agrégez deux ou trois APIs upstream derrière une seule spec côté consommateur — votre SPA ou app mobile parle à un unique endpoint typé.

S'associe à

Parser OpenAPI

Chargez n'importe quelle spec externe dans le même modèle que celui utilisé par le serveur — même validation, même système de types, mêmes primitives de sécurité.

SDK cloud prêts à l'emploi

Plus de 1 195 SDK générés pour AWS, Azure, GCP, Stripe, GitHub, Kubernetes et bien d'autres — votre serveur peut appeler chacun d'eux avec la même famille de composants.

sgcWebSockets

WebSocket, MQTT, AMQP, WebRTC, IA/LLM, IoT — tout ce que le serveur HTTP peut héberger à côté de votre surface REST.

sgcSign

Signez les bodies de requête et de réponse avec XAdES / PAdES / CAdES pour les secteurs réglementés — intégrité de niveau eIDAS sur chaque opération.

Meilleur rapport qualité-prix : All-AccessTous les produits eSeGeCe, Support Premium inclus, à partir de €1,059/an.
Voir les tarifs All-Access

Construisez votre premier serveur OpenAPI en quelques minutes

Téléchargez la version d'essai gratuite. Le serveur complet, les deux UI, tous les schémas d'auth — pas de limite de fonctionnalités, pas de bombe à retardement pendant l'évaluation.