Delphi용 OpenAPI 서버

TsgcWSAPIServer_OpenAPI는 여러분이 로드한 OpenAPI 3.x 문서를 서비스하고, 들어오는 모든 요청을 문서와 대조하며, 핸들러가 실행되기 전에 요청을 검증하고, 같은 포트에서 문서와 Swagger UI 페이지를 게시합니다. 하나의 Delphi 컴포넌트를 TsgcHTTPServer에 붙이기만 하면 됩니다.

OpenAPI 3.0 및 3.1
HTTP/2 + TLS 1.3
/docs의 Swagger UI
Spec-first 또는 Code-first

TsgcWSAPIServer_OpenAPI

OpenAPI 문서를 실행 중이며 검증되고 스스로 문서화되는 REST 서버로 바꿔주는 하나의 Delphi 컴포넌트입니다.

컴포넌트 클래스

TsgcWSAPIServer_OpenAPI, sgcWebSocket_Server_API_OpenAPI에 선언되어 있습니다

호스트 서버

ServerTsgcHTTPServer, TsgcHTTPRESTServer 또는 TsgcWebSocketHTTPServer를 대입하세요. 포트, 바인딩, TLS는 호스트가 소유합니다.

스펙 형식

OpenAPI 3.0 및 3.1 문서, LoadFromFileLoadFromString이 JSON으로 읽습니다

두 가지 워크플로

이미 가지고 있는 문서로 시작하는 Spec-first, 또는 어노테이션이 달린 Delphi 클래스로 시작하는 Code-first. Code-first는 Delphi XE7 이상이 필요합니다.

에디션

sgcOpenAPI에 포함되어 있습니다. sgcWebSockets 안에서는 Enterprise 에디션에 속하며, SGC OpenAPI 팔레트 페이지에 있습니다.

내장 엔드포인트

문서를 위한 /openapi.json과 Swagger UI를 위한 /docs, 둘 다 OpenAPIOptions.Endpoint에서 켭니다

Spec-first 또는 Code-first, 선택하세요

동일한 컴포넌트가 두 모드 모두에서 동작합니다. JSON 계약에서 시작하거나, Delphi로 API를 설명하고 스캐너가 문서를 대신 생성하도록 하세요.

1. Spec-first

LoadFromFilepetstore.json을 로드하고, OnRequest 안에서 operation id로 분기한 뒤 서비스를 시작하세요. 라우팅과 경로/쿼리 파라미터 바인딩, 검증이 모두 계약에서 나오므로 여러분은 비즈니스 로직만 작성하면 됩니다.

적합한 경우: 공유된 디자인 계약이 있는 팀, API-led 통합, 또는 스펙이 진실의 원천인 다중 언어 백엔드.

2. Code-first

평범한 Delphi 클래스에 sgcServiceContract, sgcRoute, sgcHttpGetsgcFromPath / sgcFromQuery / sgcFromBody 파라미터 어트리뷰트를 다세요. TsgcOpenAPICodeFirstScanner.GenerateSpec이 클래스의 RTTI로부터 OpenAPI 문서를 만들면, 이를 LoadFromString에 넘기고, 동일한 /openapi.json 엔드포인트가 이를 게시합니다.

적합한 경우: 빠른 프로토타이핑, 내부 서비스, 또는 기존 TIdHTTPServer / DataSnap REST 표면을 자기 문서화 API로 포팅할 때.

20줄로 만드는 동작하는 서버

컴포넌트를 만들고, 문서를 로드하고, HTTP 서버에 연결하세요. 그것이 전체 설정입니다.

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;

기본 제공되는 것: GET /pets/{petId}aOperationIdgetPetById로 설정된 채로 위 핸들러에 도달하고, GET /openapi.json은 로드한 문서를 반환하며, GET /docs는 Swagger UI를 엽니다. OpenAPIOptions.Endpoint.BasePath는 전체 표면을 프리픽스 아래로 옮기고, TLS와 HTTP/2는 호스트 서버에서 제공됩니다.

OpenAPI 문서에 선언된 파라미터는 하나의 타입화된 컨텍스트를 통해 읽히고 변환됩니다. 검증이 켜져 있으면 잘못된 타입은 핸들러가 실행되기 전에 400 Bad Request로 응답됩니다.

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;

핸들러 실행 전에 이루어지는 스키마 검증

들어오는 모든 요청은 문서가 선언한 스키마에 대해 검사됩니다. 실패하면 각 오류를 나열하는 RFC 7807 스타일의 problem 문서로 응답하며, 여러분이 명시적으로 허용하지 않는 한 핸들러에는 도달하지 않습니다.

검사 항목

type, required, propertiesadditionalProperties, enumconst, minLength / maxLength, pattern, minimum / maximum과 그 배타적 형태, multipleOf, items, minItems / maxItems, uniqueItems, nullable, not, 그리고 oneOf / anyOf / allOf. format 키워드는 date, date-time, email, ipv4, uri, uuid에 대해 적용됩니다.

범위 선택

Validation.ValidateRequest가 마스터 스위치이며, 그 자체만으로 모든 범위를 검증합니다. ValidateRequestBody, ValidateQueryParams, ValidatePathParams, ValidateHeaderParams, ValidateCookieParams로 범위를 좁힐 수 있습니다. EnforceRequired는 선택한 범위가 무엇이든 그대로 유지됩니다.

최종 결정권

OnValidationError는 operation id와 실패 목록 전체를 넘겨줍니다. Continue 플래그는 False로 도착하므로, 여러분이 의도적으로 True로 설정하지 않는 한 요청은 거부됩니다. 로드 후에는 Validation.Warnings가 문서가 사용하지만 이 검증기가 적용하지 않는 모든 스키마 키워드를 알려주므로, 빈 목록은 아무것도 놓치지 않았다는 뜻입니다.

JSON, 엔진이 작성하는 400
{
  "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"
  ]
}

스펙이 이끄는 인증 스킴

Security.EnforceSecurity를 설정하면 문서가 선언한 securitySchemes가 들어오는 요청에 적용됩니다. 여러분은 자격 증명 조회만 작성하면 되고, 컴포넌트가 요청을 파싱하며 조회 결과가 거부이면 401 또는 403으로 응답합니다.

API Key

스킴이 선언한 대로 header, query 파라미터, cookie 중 어디서든 읽습니다. OnValidateAPIKey가 스킴, 이름, 위치, 키를 받아 Valid로 응답합니다.

HTTP Basic

Authorization 헤더는 자동으로 파싱됩니다. OnValidateBasic이 사용자와 비밀번호를 받아 Valid로 응답합니다. 자격 증명은 절대 로그에 기록되지 않습니다.

Bearer와 JWT

Security.JWTSecret이 토큰을 검증합니다. HMAC 시크릿은 그대로 사용되고, -----BEGIN을 포함하는 값은 PEM 공개 키로 취급됩니다. ValidateExpiration, Issuer, Audience가 claim을 검사합니다.

직접 만드는 검증기

JWTSecret을 비워두면 토큰은 존재 여부만 확인되므로, OnValidateBearer가 이를 여러분의 토큰 서비스로 넘기고 Valid로 응답하게 할 수 있습니다.

401 또는 403

실패한 요청은 401로 응답되며, 인증은 됐지만 권한 범위만 부족했다면 403으로 응답됩니다. OnAuthenticate가 먼저 실행되고, 여러분이 Authenticated를 해제하는 순간 401로 거부합니다.

코드가 없어도 되는 목업

Mock.Enabled는 핸들러가 없는 작업에 문서 자체의 예제와 스키마로 Mock.StatusCode와 함께 응답하므로, 프런트엔드 팀이 구현이 작성되는 동안에도 작업할 수 있습니다.

Delphi, 여러분의 코드로 검증하는 bearer 토큰
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

외부 종속성도, Node.js도, 배포 파이프라인에서의 문서 빌드도 필요 없습니다. 컴포넌트가 페이지를 직접 작성하며, 서버가 실제로 서빙하는 문서를 그대로 읽습니다.

/openapi.json

로드한 문서이며, Endpoint.ServeSpec이 켜져 있을 때 서빙됩니다. 서버가 실제로 라우팅하는 내용과 항상 일치합니다. sgcOpenAPI를 포함해 어떤 클라이언트 생성기든 이 URL을 가리키게 하세요.

/docs

Endpoint.ServeSwaggerUI가 켜져 있을 때 서빙되는 인터랙티브 Swagger UI 페이지입니다. 작업을 직접 호출하고, 스키마를 탐색하고, 예제를 확인하세요. 모두 여러분이 실행 중인 서버가 직접 제공합니다.

버전 고정, 또는 완전 오프라인

페이지는 기본적으로 공용 CDN에서 CSS와 JavaScript를 로드합니다. Endpoint.SwaggerUIBaseURL이 버전을 고정하고, Endpoint.SwaggerUIAssetsPathswagger-ui.cssswagger-ui-bundle.js를 로컬 폴더에서 서빙하므로, 에어갭 환경의 머신에서도 동작합니다.

모든 것이 OpenAPIOptions 안에 있습니다

다섯 개의 영속적인 하위 객체이며, 모두 Object Inspector에 보이고 런타임에도 대입할 수 있습니다.

Endpoint

BasePath는 모든 라우트와 두 내장 엔드포인트에 접두어를 붙입니다. ServeSpecServeSwaggerUI가 이들을 켜고 끕니다. SpecFile은 둘 중 어느 쪽도 아닌 첫 요청에서 지연 로드되므로, 문서가 첫 호출부터 완전해야 한다면 LoadFromFile을 사용하세요.

Validation

ValidateRequest와 다섯 개의 범위 스위치, 그리고 EnforceRequired. Warnings는 각 로드 후, 문서가 사용하지만 이 검증기가 적용하지 않는 스키마 키워드를 알려줍니다.

CORS

Enabled, AllowOrigins, AllowHeaders, AllowMethods. 엔진은 자신의 문서가 소유한 경로에 응답을 붙이므로, 호스트 서버가 소유한 경로에는 동일한 값을 호스트 서버에도 설정하세요.

Security

EnforceSecurity, JWTSecret, ValidateExpiration, Issuer, Audience. 내장 검사가 판단할 수 없는 것은 모두 OnValidateAPIKey, OnValidateBasic, OnValidateBearer로 전달됩니다.

Mock

EnabledStatusCode. 핸들러가 없는 작업은 문서 자체의 예제와 스키마로 응답되므로, 구현이 존재하기 전에도 계약을 호출할 수 있습니다.

의도적인 Not Implemented

HandledFalse로 두면 엔진은 라우팅 실수처럼 보이는 404 대신, 작업 이름을 명시한 501 Not Implemented로 응답합니다.

하나의 HTTP 서버, 여러 표면

TsgcWSAPIServer_OpenAPI는 WebSocket 엔드포인트, AI/LLM 스트림, 정적 파일을 호스팅하는 동일한 sgcWebSockets HTTP 서버에 연결됩니다. 포트 하나, TLS 인증서 하나, 로그 스트림 하나.

서버가 스위치입니다

Active 속성은 없습니다. Server에 값을 대입하면 컴포넌트가 연결되고, nil로 설정하면 분리되며, 둘 다 호스트 서버가 계속 실행되는 동안 이루어집니다. 분리되면 문서가 소유한 경로는 그대로 여러분의 일반 핸들러로 통과합니다.

서버를 통째로 가로채지 않습니다

모든 요청은 먼저 컴포넌트에 전달되며, 컴포넌트는 자신의 문서가 선언한 경로에만 응답합니다. 나머지는 예전처럼 OnCommandGet에 도달하므로, 계약 우선 구간이 직접 작성한 라우트, DocumentRoot의 정적 콘텐츠와 한 포트 위에서 나란히 공존합니다.

호스트의 TLS와 HTTP/2

포트, 바인딩, 인증서, HTTP/2 협상은 모두 호스트 서버에 속하므로 REST 표면은 이를 그대로 물려받습니다. TsgcHTTPRESTServer에 연결하면 그 서버의 CORS, 메트릭, 헬스 체크, 테넌시도 함께 적용됩니다.

일반적인 배포 사례

퍼블릭 REST API

버전 관리되고 계약으로 테스트되며, 고객이 /openapi.json에서 다운로드할 수 있는 자동 생성 SDK 제공.

내부 마이크로서비스

리팩토링에서도 살아남는 서비스 간 계약 — 스펙이 곧 통합 테스트입니다.

산업/IoT 게이트웨이

동일한 Delphi 바이너리에서 문서화된 REST 제어 평면과 MQTT 또는 WebSocket 텔레메트리 표면을 함께 노출하는 엣지 디바이스.

웹훅 수신기

각 공급자의 웹훅 페이로드가 타입화된 Pascal 레코드가 됩니다 — Stripe, GitHub, Twilio, Slack — 검증과 멱등성이 기본 내장됩니다.

레거시 현대화

비즈니스 로직을 다시 작성하지 않고도 오래된 DataSnap 또는 RemObjects 백엔드를 깔끔한 OpenAPI 표면 뒤로 감싸세요.

BFF (Backend-for-Frontend)

두세 개의 업스트림 API를 소비자에 맞춘 하나의 스펙 뒤로 집계하세요 — SPA나 모바일 앱은 단일 타입 엔드포인트와 대화합니다.

함께 사용

OpenAPI Parser

외부 스펙을 서버가 사용하는 동일한 모델에 로드하세요 — 동일한 검증, 동일한 타입 시스템, 동일한 보안 프리미티브.

사전 빌드된 클라우드 SDK

AWS, Azure, GCP, Stripe, GitHub, Kubernetes 등을 위한 1,195개 이상의 생성된 SDK — 서버는 동일한 컴포넌트 패밀리로 이들 중 어느 것이든 호출할 수 있습니다.

sgcWebSockets

WebSocket, MQTT, AMQP, WebRTC, AI/LLM, IoT — HTTP 서버가 REST 표면과 나란히 호스팅할 수 있는 모든 것.

sgcSign

규제 산업을 위해 XAdES / PAdES / CAdES로 요청 및 응답 본문에 서명하세요 — 모든 작업에 eIDAS급 무결성.

최고의 가성비: All-Access모든 eSeGeCe 제품과 프리미엄 지원이 포함되어 연 €1,059부터 이용할 수 있어요.
All-Access 가격 보기

몇 분 안에 첫 OpenAPI 서버를 만드세요

무료 평가판을 다운로드하세요. 전체 서버, 두 UI 모두, 모든 인증 스킴 — 평가 기간 동안 기능 제한도, 시한 폭탄도 없습니다.