Servidor OpenAPI para Delphi

TsgcWSAPIServer_OpenAPI sirve el documento OpenAPI 3.x que cargas, compara cada solicitud entrante con él, valida la solicitud antes de que se ejecute tu handler, y publica el documento y una página de Swagger UI desde el mismo puerto. Un componente Delphi, conectado a un TsgcHTTPServer.

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

TsgcWSAPIServer_OpenAPI

Un componente Delphi que convierte un documento OpenAPI en un servidor REST en ejecución, validado y autodocumentado.

Clase de componente

TsgcWSAPIServer_OpenAPI, declarado en sgcWebSocket_Server_API_OpenAPI

Servidor anfitrión

Asigna a Server un TsgcHTTPServer, un TsgcHTTPRESTServer o un TsgcWebSocketHTTPServer. El anfitrión es dueño del puerto, los bindings y el TLS.

Formato de la spec

Documentos OpenAPI 3.0 y 3.1, leídos como JSON por LoadFromFile y LoadFromString

Dos flujos de trabajo

Spec-first a partir de un documento que ya tienes, o code-first desde una clase Delphi con atributos. Code-first necesita Delphi XE7 o posterior.

Edición

Se incluye con sgcOpenAPI. Dentro de sgcWebSockets pertenece a la edición Enterprise, en la página de paleta SGC OpenAPI.

Endpoints integrados

/openapi.json para el documento y /docs para Swagger UI, ambos activados en OpenAPIOptions.Endpoint

Spec-first o Code-first, Tú Eliges

El mismo componente funciona en ambos modos. Empieza desde un contrato JSON, o describe la API en Delphi y deja que el escáner genere el documento por ti.

1. Spec-first

Carga petstore.json con LoadFromFile, despacha por el operation id dentro de OnRequest, y empieza a servir. El enrutado, el binding de parámetros de path y query, y la validación vienen todos del contrato, así que solo escribes la lógica de negocio.

Ideal para: equipos con un contrato de diseño compartido, integración guiada por la API o backends políglotas donde la spec es la fuente de verdad.

2. Code-first

Anota una clase Delphi normal con sgcServiceContract, sgcRoute, sgcHttpGet y los atributos de parámetro sgcFromPath / sgcFromQuery / sgcFromBody. TsgcOpenAPICodeFirstScanner.GenerateSpec construye el documento OpenAPI a partir de la RTTI de la clase, se lo pasas a LoadFromString, y el mismo endpoint /openapi.json lo publica.

Ideal para: prototipado rápido, servicios internos o migrar una superficie REST de TIdHTTPServer / DataSnap existente a una API autodocumentada.

Un Servidor Funcional en 20 Líneas

Crea el componente, carga un documento, conéctalo a un servidor HTTP. Esa es toda la configuración.

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;

Lo que obtienes desde el primer momento: GET /pets/{petId} llega al handler de arriba con aOperationId puesto a getPetById, GET /openapi.json devuelve el documento que cargaste, GET /docs abre Swagger UI. OpenAPIOptions.Endpoint.BasePath mueve toda la superficie bajo un prefijo, y el TLS y el HTTP/2 vienen del servidor anfitrión.

Los parámetros declarados en el documento OpenAPI se leen y se convierten a través de un único contexto tipado. Con la validación activada, un tipo incorrecto se responde con 400 Bad Request antes de que se ejecute tu handler.

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;

Validación de Esquemas Antes de que se Ejecute tu Handler

Cada solicitud entrante se comprueba contra los esquemas que declara el documento. Un fallo se responde con un documento de problema al estilo RFC 7807 que enumera cada error, y nunca llega a tu handler salvo que tú lo decidas.

Qué se comprueba

type, required, properties y additionalProperties, enum y const, minLength / maxLength, pattern, minimum / maximum con sus formas exclusivas, multipleOf, items, minItems / maxItems, uniqueItems, nullable, not, y oneOf / anyOf / allOf. La palabra clave format se aplica para date, date-time, email, ipv4, uri y uuid.

Elige el alcance

Validation.ValidateRequest es el interruptor principal y por sí solo valida todos los alcances. Acótalo con ValidateRequestBody, ValidateQueryParams, ValidatePathParams, ValidateHeaderParams y ValidateCookieParams. EnforceRequired se mantiene en el alcance que elijas.

Ten la última palabra

OnValidationError te entrega el operation id y la lista completa de fallos. Su bandera Continue llega como False, así que la solicitud se rechaza salvo que tú la pongas deliberadamente en True. Tras cada carga, Validation.Warnings nombra cada palabra clave del esquema que usa el documento y que no se aplica, así que una lista vacía significa que nada quedó sin comprobar.

JSON, el 400 que escribe el motor
{
  "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"
  ]
}

Esquemas de Auth Gobernados por la Spec

Activa Security.EnforceSecurity y los securitySchemes que declara el documento se aplican a las solicitudes entrantes. Tú escribes la búsqueda de credenciales, el componente parsea la solicitud y responde 401 o 403 cuando esa búsqueda dice que no.

API Key

Se lee desde una cabecera, un parámetro de query o una cookie, según lo que declare el esquema. OnValidateAPIKey recibe el esquema, el nombre, la ubicación y la clave, y responde a través de Valid.

HTTP Basic

La cabecera Authorization se parsea por ti. OnValidateBasic recibe el usuario y la contraseña y responde a través de Valid. Las credenciales nunca se escriben en el log.

Bearer y JWT

Security.JWTSecret verifica el token. Un secreto HMAC se usa tal cual, un valor que contiene -----BEGIN se trata como una clave pública PEM. ValidateExpiration, Issuer y Audience comprueban los claims.

Tu propio verificador

Deja JWTSecret vacío y el token solo se comprueba por presencia, así OnValidateBearer puede pasárselo a tu propio servicio de tokens y responder a través de Valid.

401 o 403

Una solicitud que falla se responde con 401, o con 403 cuando se autenticó pero le faltó alcance. OnAuthenticate se ejecuta primero y rechaza con 401 en el momento en que limpias Authenticated.

Mock antes de que exista el código

Mock.Enabled responde una operación sin handler a partir de los propios ejemplos y esquemas del documento, con Mock.StatusCode, para que un equipo de front end pueda trabajar mientras se escribe la implementación.

Delphi, token bearer verificado por tu propio código
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 Embebido

Sin dependencia externa, sin Node.js, sin generación de documentación en el pipeline de despliegue. El componente escribe la página él mismo y lee el documento que tu servidor está sirviendo de verdad.

/openapi.json

El documento que cargaste, servido cuando Endpoint.ServeSpec está activo. Siempre en sintonía con lo que el servidor realmente enruta. Apunta cualquier generador de cliente a esta URL, sgcOpenAPI incluido.

/docs

La página interactiva de Swagger UI, servida cuando Endpoint.ServeSwaggerUI está activo. Prueba operaciones, navega esquemas, lee los ejemplos, todo alimentado por tu propio servidor en ejecución.

Fijado, o completamente offline

La página carga su CSS y su JavaScript desde un CDN público por defecto. Endpoint.SwaggerUIBaseURL fija una versión, y Endpoint.SwaggerUIAssetsPath sirve swagger-ui.css y swagger-ui-bundle.js desde una carpeta local, así que una máquina sin acceso a internet también funciona.

Todo Vive Bajo OpenAPIOptions

Cinco subobjetos persistentes, todos visibles en el Object Inspector, todos asignables en tiempo de ejecución.

Endpoint

BasePath antepone un prefijo a cada ruta y a los dos endpoints integrados. ServeSpec y ServeSwaggerUI los activan. SpecFile se carga de forma perezosa, en la primera solicitud que no sea ninguno de los dos, así que usa LoadFromFile cuando el documento deba estar completo desde la primera llamada.

Validation

ValidateRequest más los cinco interruptores de alcance, y EnforceRequired. Warnings informa, tras cada carga, de las palabras clave del esquema que usa el documento y que este validador no aplica.

CORS

Enabled, AllowOrigins, AllowHeaders y AllowMethods. El motor sella las respuestas en las rutas que posee su documento, así que dale al servidor anfitrión los mismos valores para las rutas que posee él.

Security

EnforceSecurity, JWTSecret, ValidateExpiration, Issuer y Audience. Todo lo que las comprobaciones integradas no pueden decidir llega a OnValidateAPIKey, OnValidateBasic o OnValidateBearer.

Mock

Enabled y StatusCode. Una operación sin handler se responde a partir de los propios ejemplos y esquemas del documento, así que el contrato se puede invocar antes de que exista la implementación.

Not Implemented, a propósito

Deja Handled en False y el motor responde 501 Not Implemented nombrando la operación, en lugar de un 404 que parece un error de enrutado.

Un Servidor HTTP, Muchas Superficies

TsgcWSAPIServer_OpenAPI se conecta al mismo servidor HTTP de sgcWebSockets que aloja tus endpoints WebSocket, streams de IA/LLM y archivos estáticos. Un puerto, un certificado TLS, un stream de logs.

Server es el interruptor

No existe la propiedad Active. Asignar Server conecta el componente, ponerlo a nil lo desconecta, ambos mientras el servidor anfitrión sigue en ejecución. Desconectado, las rutas que posee su documento pasan directamente a tu handler habitual.

Nunca toma el control del servidor

Cada solicitud se ofrece primero al componente, y este solo responde a las rutas que declara su documento. Todo lo demás llega a OnCommandGet como antes, así que una sección contract-first convive con rutas escritas a mano y contenido estático desde DocumentRoot, todo en un mismo puerto.

El TLS y el HTTP/2 del anfitrión

El puerto, los bindings, el certificado y la negociación HTTP/2 pertenecen al servidor anfitrión, así que la superficie REST los hereda sin cambios. Conéctalo a un TsgcHTTPRESTServer y el CORS, las métricas, la salud y la tenencia de ese servidor también se aplican.

Despliegues Típicos

APIs REST públicas

Versionadas, probadas por contrato, con SDKs autogenerados que tus clientes pueden descargar desde /openapi.json.

Microservicios internos

Contratos servicio a servicio que sobreviven a los refactors — la spec es el test de integración.

Gateways industriales / IoT

Dispositivos edge que exponen un plano de control REST documentado más una superficie de telemetría MQTT o WebSocket desde el mismo binario Delphi.

Receptores de webhook

El payload de webhook de cada proveedor se convierte en un record Pascal tipado — Stripe, GitHub, Twilio, Slack — con validación e idempotencia integradas.

Modernización de legacy

Envuelve un backend antiguo de DataSnap o RemObjects detrás de una superficie OpenAPI limpia sin reescribir la lógica de negocio.

BFF (Backend-for-Frontend)

Agrega dos o tres APIs upstream detrás de una única spec con forma de consumidor — tu SPA o app móvil habla con un único endpoint tipado.

Combina Con

OpenAPI Parser

Carga cualquier spec externa en el mismo modelo que usa el servidor — misma validación, mismo sistema de tipos, mismas primitivas de seguridad.

SDKs cloud preconstruidos

Más de 1.195 SDKs generados para AWS, Azure, GCP, Stripe, GitHub, Kubernetes y más — tu servidor puede llamar a cualquiera de ellos con la misma familia de componentes.

sgcWebSockets

WebSocket, MQTT, AMQP, WebRTC, IA/LLM, IoT — todo lo que el servidor HTTP puede alojar junto a tu superficie REST.

sgcSign

Firma cuerpos de solicitud y respuesta con XAdES / PAdES / CAdES para industrias reguladas — integridad de nivel eIDAS en cada operación.

La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

Construye Tu Primer Servidor OpenAPI en Minutos

Descarga la prueba gratuita. El servidor completo, ambas UIs, todos los esquemas de auth — sin límites de funciones, sin bombas de tiempo durante la evaluación.