Servidor OpenAPI para Delphi

TsgcWSAPIServer_OpenAPI serve o documento OpenAPI 3.x que você carrega, compara cada requisição recebida com ele, valida a requisição antes de o seu handler rodar, e publica o documento e uma página Swagger UI a partir da mesma porta. Um único componente Delphi, anexado a um TsgcHTTPServer.

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

TsgcWSAPIServer_OpenAPI

Um único componente Delphi que transforma um documento OpenAPI em um servidor REST em execução, validado e autodocumentado.

Classe do componente

TsgcWSAPIServer_OpenAPI, declarado em sgcWebSocket_Server_API_OpenAPI

Servidor hospedeiro

Atribua a Server um TsgcHTTPServer, um TsgcHTTPRESTServer ou um TsgcWebSocketHTTPServer. O hospedeiro é o dono da porta, dos bindings e do TLS.

Formato da spec

Documentos OpenAPI 3.0 e 3.1, lidos como JSON por LoadFromFile e LoadFromString

Dois fluxos de trabalho

Spec-first a partir de um documento que você já tem, ou code-first a partir de uma classe Delphi anotada. Code-first exige Delphi XE7 ou mais recente.

Edição

Vem com o sgcOpenAPI. Dentro do sgcWebSockets pertence à edição Enterprise, na página de paleta SGC OpenAPI.

Endpoints embutidos

/openapi.json para o documento e /docs para o Swagger UI, ambos ativados em OpenAPIOptions.Endpoint

Spec-first ou Code-first, Você Escolhe

O mesmo componente roda em ambos os modos. Comece a partir de um contrato JSON, ou descreva a API em Delphi e deixe o scanner gerar o documento para você.

1. Spec-first

Carregue petstore.json com LoadFromFile, despache pelo operation id dentro de OnRequest, e comece a servir. Roteamento, binding de parâmetros de path e query e validação vêm todos do contrato, então você só escreve a lógica de negócio.

Ideal para: equipes com um contrato de design compartilhado, integração API-led ou back-ends poliglotas em que a spec é a fonte da verdade.

2. Code-first

Anote uma classe Delphi comum com sgcServiceContract, sgcRoute, sgcHttpGet e os atributos de parâmetro sgcFromPath / sgcFromQuery / sgcFromBody. O TsgcOpenAPICodeFirstScanner.GenerateSpec constrói o documento OpenAPI a partir do RTTI da classe, você o entrega a LoadFromString, e o mesmo endpoint /openapi.json o publica.

Ideal para: prototipagem rápida, serviços internos ou portar uma superfície REST existente de TIdHTTPServer / DataSnap para uma API autodocumentada.

Um Servidor Funcional em 20 Linhas

Crie o componente, carregue um documento, anexe-o a um servidor HTTP. Essa é toda a configuração.

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;

O que você ganha de cara: GET /pets/{petId} chega ao handler acima com aOperationId definido como getPetById, GET /openapi.json devolve o documento que você carregou, GET /docs abre o Swagger UI. OpenAPIOptions.Endpoint.BasePath move toda a superfície para debaixo de um prefixo, e o TLS e o HTTP/2 vêm do servidor hospedeiro.

Os parâmetros declarados no documento OpenAPI são lidos e convertidos através de um único contexto tipado. Com a validação ativada, um tipo errado é respondido com 400 Bad Request antes de o seu handler rodar.

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;

Validação de Schema Antes de o Seu Handler Rodar

Toda requisição recebida é checada contra os schemas que o documento declara. Uma falha é respondida com um documento de erro no estilo RFC 7807 listando cada erro, e nunca chega ao seu handler a menos que você diga o contrário.

O que é checado

type, required, properties e additionalProperties, enum e const, minLength / maxLength, pattern, minimum / maximum com suas formas exclusivas, multipleOf, items, minItems / maxItems, uniqueItems, nullable, not, e oneOf / anyOf / allOf. A palavra-chave format é aplicada para date, date-time, email, ipv4, uri e uuid.

Escolha o escopo

Validation.ValidateRequest é a chave mestra e, sozinha, valida todos os escopos. Restrinja com ValidateRequestBody, ValidateQueryParams, ValidatePathParams, ValidateHeaderParams e ValidateCookieParams. EnforceRequired permanece ativo qualquer que seja o escopo escolhido.

Você tem a última palavra

OnValidationError te entrega o operation id e a lista completa de falhas. O seu flag Continue chega como False, então a requisição é rejeitada a menos que você o defina deliberadamente como True. Depois de um load, Validation.Warnings lista cada palavra-chave de schema que o documento usa e que não é aplicada, então uma lista vazia significa que nada ficou sem checagem.

JSON, o 400 que o motor grava
{
  "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 Conduzidos pela Spec

Defina Security.EnforceSecurity e os securitySchemes que o documento declara são aplicados às requisições recebidas. Você escreve o lookup de credenciais, o componente analisa a requisição e responde 401 ou 403 quando o lookup diz não.

API Key

Lida de um header, um parâmetro de query ou um cookie, conforme o esquema declarar. OnValidateAPIKey recebe o esquema, o nome, a localização e a chave, e responde através de Valid.

HTTP Basic

O header Authorization é analisado para você. OnValidateBasic recebe o usuário e a senha e responde através de Valid. As credenciais nunca são gravadas no log.

Bearer e JWT

Security.JWTSecret verifica o token. Um segredo HMAC é usado como está, um valor contendo -----BEGIN é tratado como uma chave pública PEM. ValidateExpiration, Issuer e Audience checam as claims.

Seu próprio verificador

Deixe JWTSecret vazio e o token só é checado quanto à presença, então OnValidateBearer pode entregá-lo ao seu próprio serviço de tokens e responder através de Valid.

401 ou 403

Uma requisição que falha é respondida com 401, ou 403 quando ela se autenticou e faltou apenas escopo. OnAuthenticate roda primeiro e rejeita com 401 assim que você limpa Authenticated.

Mock antes do código existir

Mock.Enabled responde a uma operação sem handler a partir dos próprios exemplos e schemas do documento, com Mock.StatusCode, para que uma equipe de front end possa trabalhar enquanto a implementação é escrita.

Delphi, token bearer verificado pelo seu próprio 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 Embutido

Sem dependência externa, sem Node.js, sem build de documentação no pipeline de deploy. O componente escreve a página sozinho e ela lê o documento que o seu servidor está realmente servindo.

/openapi.json

O documento que você carregou, servido quando Endpoint.ServeSpec está ativo. Sempre em sincronia com o que o servidor realmente roteia. Aponte qualquer gerador de cliente para essa URL, incluindo o sgcOpenAPI.

/docs

A página interativa do Swagger UI, servida quando Endpoint.ServeSwaggerUI está ativo. Experimente operações, navegue por schemas, leia os exemplos, tudo alimentado pelo seu próprio servidor em execução.

Fixado, ou totalmente offline

Por padrão, a página carrega seu CSS e JavaScript de um CDN público. Endpoint.SwaggerUIBaseURL fixa uma versão, e Endpoint.SwaggerUIAssetsPath serve swagger-ui.css e swagger-ui-bundle.js a partir de uma pasta local, para que uma máquina isolada da rede também funcione.

Tudo Vive em OpenAPIOptions

Cinco subobjetos persistentes, todos visíveis no Object Inspector, todos atribuíveis em tempo de execução.

Endpoint

BasePath prefixa cada rota e os dois endpoints embutidos. ServeSpec e ServeSwaggerUI os alternam. SpecFile é carregado de forma preguiçosa, na primeira requisição que não é nenhum dos dois, então use LoadFromFile quando o documento precisar estar completo já na primeira chamada.

Validation

ValidateRequest mais as cinco chaves de escopo, e EnforceRequired. Warnings relata, após cada load, as palavras-chave de schema que o documento usa e que este validador não aplica.

CORS

Enabled, AllowOrigins, AllowHeaders e AllowMethods. O motor carimba as respostas nos caminhos que o seu documento possui, então dê ao servidor hospedeiro os mesmos valores para os caminhos que ele possui.

Security

EnforceSecurity, JWTSecret, ValidateExpiration, Issuer e Audience. Tudo o que as checagens embutidas não conseguem decidir chega a OnValidateAPIKey, OnValidateBasic ou OnValidateBearer.

Mock

Enabled e StatusCode. Uma operação sem handler é respondida a partir dos próprios exemplos e schemas do documento, para que o contrato seja chamável antes de a implementação existir.

Not Implemented, de propósito

Deixe Handled em False e o motor responde 501 Not Implemented nomeando a operação, em vez de um 404 que parece um erro de roteamento.

Um Servidor HTTP, Várias Superfícies

O TsgcWSAPIServer_OpenAPI se conecta ao mesmo servidor HTTP do sgcWebSockets que hospeda seus endpoints WebSocket, streams de IA/LLM e arquivos estáticos. Uma porta, um certificado TLS, um stream de logs.

O Server é o interruptor

Não existe propriedade Active. Atribuir Server anexa o componente, defini-lo como nil o desanexa, ambos com o servidor hospedeiro continuando em execução. Desanexado, os caminhos que o seu documento possui caem direto no seu handler comum.

Ele nunca toma conta do servidor

Cada requisição é oferecida primeiro ao componente, que responde apenas os caminhos que o seu documento declara. Todo o resto chega a OnCommandGet como antes, então uma seção contract-first convive com rotas escritas à mão e conteúdo estático de DocumentRoot, tudo em uma única porta.

O TLS e o HTTP/2 do hospedeiro

A porta, os bindings, o certificado e a negociação HTTP/2 pertencem ao servidor hospedeiro, então a superfície REST os herda sem alterações. Anexe-o a um TsgcHTTPRESTServer e o CORS, as métricas, a saúde e a tenancy desse servidor também se aplicam.

Deployments Típicos

APIs REST públicas

Versionadas, testadas por contrato, com SDKs auto-gerados que seus clientes podem baixar de /openapi.json.

Microsserviços internos

Contratos serviço-a-serviço que sobrevivem a refactors — a spec é o teste de integração.

Gateways industriais / IoT

Dispositivos de edge expondo um plano de controle REST documentado mais uma superfície de telemetria MQTT ou WebSocket a partir do mesmo binário Delphi.

Receptores de webhook

O payload do webhook de cada provedor vira um record Pascal tipado — Stripe, GitHub, Twilio, Slack — com validação e idempotência embutidas.

Modernização de legado

Envolva um back-end antigo de DataSnap ou RemObjects atrás de uma superfície OpenAPI limpa sem reescrever a lógica de negócio.

BFF (Backend-for-Frontend)

Agregue duas ou três APIs upstream atrás de uma única spec com formato do consumidor — sua SPA ou app mobile fala com um único endpoint tipado.

Combina com

Parser OpenAPI

Carregue qualquer spec externa no mesmo modelo usado pelo servidor — mesma validação, mesmo sistema de tipos, mesmas primitivas de segurança.

SDKs cloud prontos

Mais de 1.195 SDKs gerados para AWS, Azure, GCP, Stripe, GitHub, Kubernetes e mais — seu servidor pode chamar qualquer um deles com a mesma família de componentes.

sgcWebSockets

WebSocket, MQTT, AMQP, WebRTC, IA/LLM, IoT — tudo que o servidor HTTP consegue hospedar ao lado da sua superfície REST.

sgcSign

Assine bodies de requisição e resposta com XAdES / PAdES / CAdES para setores regulados — integridade nível eIDAS em cada operação.

Melhor custo-benefício: All-AccessTodos os produtos da eSeGeCe, com Suporte Premium incluído, a partir de €1,059/ano.
Ver preços do All-Access

Construa Seu Primeiro Servidor OpenAPI em Minutos

Baixe a versão gratuita. O servidor completo, as duas UIs, todos os esquemas de auth — sem limites de funcionalidade, sem bomba-relógio durante a avaliação.