Server OpenAPI per Delphi

TsgcWSAPIServer_OpenAPI serve il documento OpenAPI 3.x che carichi, confronta ogni richiesta in arrivo con la specifica, valida la richiesta prima che il tuo handler venga eseguito e pubblica il documento e una pagina Swagger UI dalla stessa porta. Un unico componente Delphi, collegato a un TsgcHTTPServer.

OpenAPI 3.0 e 3.1
HTTP/2 + TLS 1.3
Swagger UI su /docs
Spec-first o Code-first

TsgcWSAPIServer_OpenAPI

Un unico componente Delphi che trasforma un documento OpenAPI in un server REST in esecuzione, validato e auto-documentato.

Classe del componente

TsgcWSAPIServer_OpenAPI, dichiarato in sgcWebSocket_Server_API_OpenAPI

Server host

Assegna a Server un TsgcHTTPServer, un TsgcHTTPRESTServer o un TsgcWebSocketHTTPServer. L'host possiede la porta, i binding e il TLS.

Formato spec

Documenti OpenAPI 3.0 e 3.1, letti come JSON da LoadFromFile e LoadFromString

Due workflow

Spec-first da un documento che hai già, oppure code-first da una classe Delphi con attributi. Code-first richiede Delphi XE7 o successivo.

Edizione

Incluso in sgcOpenAPI. All'interno di sgcWebSockets appartiene all'edizione Enterprise, nella pagina della palette SGC OpenAPI.

Endpoint integrati

/openapi.json per il documento e /docs per Swagger UI, entrambi attivabili in OpenAPIOptions.Endpoint

Spec-first o Code-first, Scegli tu

Lo stesso componente funziona in entrambe le modalità. Parti da un contratto JSON, oppure descrivi l'API in Delphi e lascia che sia lo scanner a generare il documento per te.

1. Spec-first

Carica petstore.json con LoadFromFile, distribuisci in base all'operation id dentro OnRequest e inizia a servire. Routing, binding dei parametri di path e query e validazione arrivano tutti dal contratto, quindi scrivi solo la logica di business.

Ideale per: team con un contratto di design condiviso, integrazione API-led o back-end poliglotti dove la spec è la fonte di verità.

2. Code-first

Annota una semplice classe Delphi con sgcServiceContract, sgcRoute, sgcHttpGet e gli attributi parametro sgcFromPath / sgcFromQuery / sgcFromBody. TsgcOpenAPICodeFirstScanner.GenerateSpec costruisce il documento OpenAPI a partire dalla RTTI della classe, lo passi a LoadFromString e lo stesso endpoint /openapi.json lo pubblica.

Ideale per: prototipazione rapida, servizi interni o porting di una superficie REST TIdHTTPServer / DataSnap esistente verso un'API auto-documentata.

Un Server Funzionante in 20 Righe

Crea il componente, carica un documento, collegalo a un server HTTP. Questa è tutta la configurazione.

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;

Cosa ottieni subito: GET /pets/{petId} raggiunge l'handler qui sopra con aOperationId impostato a getPetById, GET /openapi.json restituisce il documento che hai caricato, GET /docs apre Swagger UI. OpenAPIOptions.Endpoint.BasePath sposta l'intera superficie sotto un prefisso, e TLS e HTTP/2 arrivano dal server host.

I parametri dichiarati nel documento OpenAPI vengono letti e convertiti tramite un unico context tipizzato. Con la validazione attiva, un tipo errato riceve risposta 400 Bad Request prima ancora che il tuo handler venga eseguito.

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;

Validazione degli Schemi Prima che il Tuo Handler Venga Eseguito

Ogni richiesta in arrivo viene verificata rispetto agli schemi dichiarati dal documento. Un errore riceve risposta con un documento problem in stile RFC 7807 che elenca ciascun errore, e non raggiunge mai il tuo handler a meno che tu non lo permetta esplicitamente.

Cosa viene controllato

type, required, properties e additionalProperties, enum e const, minLength / maxLength, pattern, minimum / maximum con le loro forme esclusive, multipleOf, items, minItems / maxItems, uniqueItems, nullable, not e oneOf / anyOf / allOf. La parola chiave format viene applicata per date, date-time, email, ipv4, uri e uuid.

Scegli l'ambito

Validation.ValidateRequest è l'interruttore principale e da solo valida ogni ambito. Restringilo con ValidateRequestBody, ValidateQueryParams, ValidatePathParams, ValidateHeaderParams e ValidateCookieParams. EnforceRequired resta attivo su qualunque ambito tu scelga.

Hai l'ultima parola

OnValidationError ti passa l'operation id e l'elenco completo dei fallimenti. Il suo flag Continue arriva a False, quindi la richiesta viene rifiutata a meno che tu non lo imposti deliberatamente a True. Dopo un caricamento, Validation.Warnings elenca ogni parola chiave dello schema che il documento usa e che non viene applicata, quindi una lista vuota significa che nulla è sfuggito al controllo.

JSON, il 400 scritto dal motore
{
  "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"
  ]
}

Schemi di Autenticazione Guidati dalla Spec

Imposta Security.EnforceSecurity e gli securitySchemes dichiarati dal documento vengono applicati alle richieste in arrivo. Tu scrivi il lookup delle credenziali, il componente analizza la richiesta e risponde 401 o 403 quando il lookup dice di no.

API Key

Letta da un header, un parametro di query o un cookie, a seconda di quanto dichiarato dallo schema. OnValidateAPIKey riceve schema, nome, posizione e chiave, e risponde tramite Valid.

HTTP Basic

L'header Authorization viene analizzato per te. OnValidateBasic riceve utente e password e risponde tramite Valid. Le credenziali non vengono mai scritte nel log.

Bearer e JWT

Security.JWTSecret verifica il token. Un segreto HMAC viene usato così com'è, un valore che contiene -----BEGIN viene trattato come chiave pubblica PEM. ValidateExpiration, Issuer e Audience verificano i claim.

Il tuo verificatore

Lascia JWTSecret vuoto e il token viene controllato solo per la sua presenza, così OnValidateBearer può passarlo al tuo servizio di token e rispondere tramite Valid.

401 o 403

Una richiesta che fallisce riceve risposta 401, oppure 403 quando si è autenticata ma non ha superato solo il controllo di scope. OnAuthenticate viene eseguito per primo e rifiuta con 401 nel momento in cui azzeri Authenticated.

Mock prima che il codice esista

Mock.Enabled risponde a un'operazione senza handler con gli esempi e gli schemi propri del documento, tramite Mock.StatusCode, così un team frontend può lavorare mentre l'implementazione viene scritta.

Delphi, bearer token verificato dal tuo codice
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 Integrato

Nessuna dipendenza esterna, niente Node.js, nessuna build di documentazione nella pipeline di deploy. Il componente scrive la pagina da sé e legge il documento che il tuo server sta realmente servendo.

/openapi.json

Il documento che hai caricato, servito quando Endpoint.ServeSpec è attivo. Sempre allineato con quello che il server instrada davvero. Punta qualsiasi generatore di client a questa URL, sgcOpenAPI incluso.

/docs

La pagina Swagger UI interattiva, servita quando Endpoint.ServeSwaggerUI è attivo. Prova le operazioni, esplora gli schemi, leggi gli esempi, tutto alimentato dal tuo server realmente in esecuzione.

Fissato a una versione, oppure completamente offline

La pagina carica il suo CSS e JavaScript da una CDN pubblica per impostazione predefinita. Endpoint.SwaggerUIBaseURL fissa una versione, e Endpoint.SwaggerUIAssetsPath serve swagger-ui.css e swagger-ui-bundle.js da una cartella locale, così funziona anche una macchina isolata dalla rete.

Tutto Vive Sotto OpenAPIOptions

Cinque sotto-oggetti persistenti, tutti visibili nell'Object Inspector, tutti assegnabili a runtime.

Endpoint

BasePath antepone un prefisso a ogni route e a entrambi gli endpoint integrati. ServeSpec e ServeSwaggerUI li attivano. SpecFile viene caricato in modo lazy, alla prima richiesta che non è nessuno dei due, quindi usa LoadFromFile quando il documento deve essere completo fin dalla prima chiamata.

Validation

ValidateRequest più i cinque interruttori di ambito, ed EnforceRequired. Warnings segnala, dopo ogni caricamento, le parole chiave dello schema che il documento usa ma che questo validatore non applica.

CORS

Enabled, AllowOrigins, AllowHeaders e AllowMethods. Il motore imposta le risposte sui path di sua proprietà, quindi dai al server host gli stessi valori per i path che possiede.

Security

EnforceSecurity, JWTSecret, ValidateExpiration, Issuer e Audience. Tutto ciò che i controlli integrati non possono decidere arriva a OnValidateAPIKey, OnValidateBasic o OnValidateBearer.

Mock

Enabled e StatusCode. A un'operazione senza handler viene risposto con gli esempi e gli schemi propri del documento, così il contratto è chiamabile prima che l'implementazione esista.

Not Implemented, di proposito

Lascia Handled a False e il motore risponde 501 Not Implemented indicando l'operazione, invece di un 404 che sembra un errore di routing.

Un server HTTP, molte superfici

TsgcWSAPIServer_OpenAPI si collega allo stesso server HTTP di sgcWebSockets che ospita i tuoi endpoint WebSocket, gli stream AI/LLM e i file statici. Una porta, un certificato TLS, uno stream di log.

Server è l'interruttore

Non esiste una proprietà Active. Assegnare Server collega il componente, impostarlo a nil lo scollega, entrambe le operazioni mentre il server host continua a funzionare. Scollegato, i path di proprietà del suo documento passano direttamente al tuo handler ordinario.

Non prende mai il controllo del server

Ogni richiesta viene offerta prima al componente, che risponde solo ai path dichiarati dal suo documento. Tutto il resto raggiunge OnCommandGet come prima, così una sezione contract-first convive con route scritte a mano e contenuti statici da DocumentRoot, tutto sulla stessa porta.

Il TLS e l'HTTP/2 dell'host

La porta, i binding, il certificato e la negoziazione HTTP/2 appartengono al server host, quindi la superficie REST li eredita senza modifiche. Collegalo a un TsgcHTTPRESTServer e si applicano anche il CORS, le metriche, l'health e il multi-tenancy di quel server.

Deployment tipici

API REST pubbliche

Versionate, testate per contratto, con SDK auto-generati che i tuoi clienti possono scaricare da /openapi.json.

Microservizi interni

Contratti servizio-a-servizio che sopravvivono ai refactor — la spec è il test di integrazione.

Gateway industriali / IoT

Dispositivi edge che espongono un control plane REST documentato più una superficie di telemetria MQTT o WebSocket dallo stesso binario Delphi.

Ricevitori di webhook

Il payload del webhook di ogni provider diventa un record Pascal tipizzato — Stripe, GitHub, Twilio, Slack — con validazione e idempotenza integrate.

Modernizzazione di legacy

Avvolgi un vecchio back-end DataSnap o RemObjects dietro una superficie OpenAPI pulita senza riscrivere la logica di business.

BFF (Backend-for-Frontend)

Aggrega due o tre API upstream dietro un'unica spec a forma di consumatore — la tua SPA o app mobile parla con un singolo endpoint tipizzato.

Si abbina a

OpenAPI Parser

Carica qualsiasi spec esterna nello stesso modello usato dal server — stessa validazione, stesso sistema di tipi, stesse primitive di sicurezza.

SDK cloud pre-costruiti

Oltre 1.195 SDK generati per AWS, Azure, GCP, Stripe, GitHub, Kubernetes e altro — il tuo server può chiamarli tutti con la stessa famiglia di componenti.

sgcWebSockets

WebSocket, MQTT, AMQP, WebRTC, AI/LLM, IoT — tutto ciò che il server HTTP può ospitare insieme alla tua superficie REST.

sgcSign

Firma i body di request e response con XAdES / PAdES / CAdES per settori regolamentati — integrità di livello eIDAS su ogni operazione.

La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Costruisci il tuo primo server OpenAPI in pochi minuti

Scarica la versione di prova gratuita. Il server completo, entrambe le UI, ogni schema di auth — nessun limite di funzionalità, nessuna bomba a tempo durante la valutazione.