Delphi용 OpenAPI 서버
TsgcWSAPIServer_OpenAPI는 여러분이 로드한 OpenAPI 3.x 문서를 서비스하고, 들어오는 모든 요청을 문서와 대조하며, 핸들러가 실행되기 전에 요청을 검증하고, 같은 포트에서 문서와 Swagger UI 페이지를 게시합니다. 하나의 Delphi 컴포넌트를 TsgcHTTPServer에 붙이기만 하면 됩니다.
TsgcWSAPIServer_OpenAPI는 여러분이 로드한 OpenAPI 3.x 문서를 서비스하고, 들어오는 모든 요청을 문서와 대조하며, 핸들러가 실행되기 전에 요청을 검증하고, 같은 포트에서 문서와 Swagger UI 페이지를 게시합니다. 하나의 Delphi 컴포넌트를 TsgcHTTPServer에 붙이기만 하면 됩니다.
OpenAPI 문서를 실행 중이며 검증되고 스스로 문서화되는 REST 서버로 바꿔주는 하나의 Delphi 컴포넌트입니다.
TsgcWSAPIServer_OpenAPI, sgcWebSocket_Server_API_OpenAPI에 선언되어 있습니다
Server에 TsgcHTTPServer, TsgcHTTPRESTServer 또는 TsgcWebSocketHTTPServer를 대입하세요. 포트, 바인딩, TLS는 호스트가 소유합니다.
OpenAPI 3.0 및 3.1 문서, LoadFromFile과 LoadFromString이 JSON으로 읽습니다
이미 가지고 있는 문서로 시작하는 Spec-first, 또는 어노테이션이 달린 Delphi 클래스로 시작하는 Code-first. Code-first는 Delphi XE7 이상이 필요합니다.
sgcOpenAPI에 포함되어 있습니다. sgcWebSockets 안에서는 Enterprise 에디션에 속하며, SGC OpenAPI 팔레트 페이지에 있습니다.
문서를 위한 /openapi.json과 Swagger UI를 위한 /docs, 둘 다 OpenAPIOptions.Endpoint에서 켭니다
동일한 컴포넌트가 두 모드 모두에서 동작합니다. JSON 계약에서 시작하거나, Delphi로 API를 설명하고 스캐너가 문서를 대신 생성하도록 하세요.
LoadFromFile로 petstore.json을 로드하고, OnRequest 안에서 operation id로 분기한 뒤 서비스를 시작하세요. 라우팅과 경로/쿼리 파라미터 바인딩, 검증이 모두 계약에서 나오므로 여러분은 비즈니스 로직만 작성하면 됩니다.
적합한 경우: 공유된 디자인 계약이 있는 팀, API-led 통합, 또는 스펙이 진실의 원천인 다중 언어 백엔드.
평범한 Delphi 클래스에 sgcServiceContract, sgcRoute, sgcHttpGet과 sgcFromPath / sgcFromQuery / sgcFromBody 파라미터 어트리뷰트를 다세요. TsgcOpenAPICodeFirstScanner.GenerateSpec이 클래스의 RTTI로부터 OpenAPI 문서를 만들면, 이를 LoadFromString에 넘기고, 동일한 /openapi.json 엔드포인트가 이를 게시합니다.
적합한 경우: 빠른 프로토타이핑, 내부 서비스, 또는 기존 TIdHTTPServer / DataSnap REST 표면을 자기 문서화 API로 포팅할 때.
컴포넌트를 만들고, 문서를 로드하고, HTTP 서버에 연결하세요. 그것이 전체 설정입니다.
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}는 aOperationId가 getPetById로 설정된 채로 위 핸들러에 도달하고,
GET /openapi.json은 로드한 문서를 반환하며,
GET /docs는 Swagger UI를 엽니다.
OpenAPIOptions.Endpoint.BasePath는 전체 표면을 프리픽스 아래로 옮기고, TLS와 HTTP/2는 호스트 서버에서 제공됩니다.
OpenAPI 문서에 선언된 파라미터는 하나의 타입화된 컨텍스트를 통해 읽히고 변환됩니다. 검증이 켜져 있으면 잘못된 타입은 핸들러가 실행되기 전에 400 Bad Request로 응답됩니다.
// 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, properties와 additionalProperties, enum과 const, 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가 문서가 사용하지만 이 검증기가 적용하지 않는 모든 스키마 키워드를 알려주므로, 빈 목록은 아무것도 놓치지 않았다는 뜻입니다.
{
"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으로 응답합니다.
스킴이 선언한 대로 header, query 파라미터, cookie 중 어디서든 읽습니다. OnValidateAPIKey가 스킴, 이름, 위치, 키를 받아 Valid로 응답합니다.
Authorization 헤더는 자동으로 파싱됩니다. OnValidateBasic이 사용자와 비밀번호를 받아 Valid로 응답합니다. 자격 증명은 절대 로그에 기록되지 않습니다.
Security.JWTSecret이 토큰을 검증합니다. HMAC 시크릿은 그대로 사용되고, -----BEGIN을 포함하는 값은 PEM 공개 키로 취급됩니다. ValidateExpiration, Issuer, Audience가 claim을 검사합니다.
JWTSecret을 비워두면 토큰은 존재 여부만 확인되므로, OnValidateBearer가 이를 여러분의 토큰 서비스로 넘기고 Valid로 응답하게 할 수 있습니다.
실패한 요청은 401로 응답되며, 인증은 됐지만 권한 범위만 부족했다면 403으로 응답됩니다. OnAuthenticate가 먼저 실행되고, 여러분이 Authenticated를 해제하는 순간 401로 거부합니다.
Mock.Enabled는 핸들러가 없는 작업에 문서 자체의 예제와 스키마로 Mock.StatusCode와 함께 응답하므로, 프런트엔드 팀이 구현이 작성되는 동안에도 작업할 수 있습니다.
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;
외부 종속성도, Node.js도, 배포 파이프라인에서의 문서 빌드도 필요 없습니다. 컴포넌트가 페이지를 직접 작성하며, 서버가 실제로 서빙하는 문서를 그대로 읽습니다.
로드한 문서이며, Endpoint.ServeSpec이 켜져 있을 때 서빙됩니다. 서버가 실제로 라우팅하는 내용과 항상 일치합니다. sgcOpenAPI를 포함해 어떤 클라이언트 생성기든 이 URL을 가리키게 하세요.
Endpoint.ServeSwaggerUI가 켜져 있을 때 서빙되는 인터랙티브 Swagger UI 페이지입니다. 작업을 직접 호출하고, 스키마를 탐색하고, 예제를 확인하세요. 모두 여러분이 실행 중인 서버가 직접 제공합니다.
페이지는 기본적으로 공용 CDN에서 CSS와 JavaScript를 로드합니다. Endpoint.SwaggerUIBaseURL이 버전을 고정하고, Endpoint.SwaggerUIAssetsPath가 swagger-ui.css와 swagger-ui-bundle.js를 로컬 폴더에서 서빙하므로, 에어갭 환경의 머신에서도 동작합니다.
다섯 개의 영속적인 하위 객체이며, 모두 Object Inspector에 보이고 런타임에도 대입할 수 있습니다.
BasePath는 모든 라우트와 두 내장 엔드포인트에 접두어를 붙입니다. ServeSpec과 ServeSwaggerUI가 이들을 켜고 끕니다. SpecFile은 둘 중 어느 쪽도 아닌 첫 요청에서 지연 로드되므로, 문서가 첫 호출부터 완전해야 한다면 LoadFromFile을 사용하세요.
ValidateRequest와 다섯 개의 범위 스위치, 그리고 EnforceRequired. Warnings는 각 로드 후, 문서가 사용하지만 이 검증기가 적용하지 않는 스키마 키워드를 알려줍니다.
Enabled, AllowOrigins, AllowHeaders, AllowMethods. 엔진은 자신의 문서가 소유한 경로에 응답을 붙이므로, 호스트 서버가 소유한 경로에는 동일한 값을 호스트 서버에도 설정하세요.
EnforceSecurity, JWTSecret, ValidateExpiration, Issuer, Audience. 내장 검사가 판단할 수 없는 것은 모두 OnValidateAPIKey, OnValidateBasic, OnValidateBearer로 전달됩니다.
Enabled와 StatusCode. 핸들러가 없는 작업은 문서 자체의 예제와 스키마로 응답되므로, 구현이 존재하기 전에도 계약을 호출할 수 있습니다.
Handled를 False로 두면 엔진은 라우팅 실수처럼 보이는 404 대신, 작업 이름을 명시한 501 Not Implemented로 응답합니다.
TsgcWSAPIServer_OpenAPI는 WebSocket 엔드포인트, AI/LLM 스트림, 정적 파일을 호스팅하는 동일한 sgcWebSockets HTTP 서버에 연결됩니다. 포트 하나, TLS 인증서 하나, 로그 스트림 하나.
Active 속성은 없습니다. Server에 값을 대입하면 컴포넌트가 연결되고, nil로 설정하면 분리되며, 둘 다 호스트 서버가 계속 실행되는 동안 이루어집니다. 분리되면 문서가 소유한 경로는 그대로 여러분의 일반 핸들러로 통과합니다.
모든 요청은 먼저 컴포넌트에 전달되며, 컴포넌트는 자신의 문서가 선언한 경로에만 응답합니다. 나머지는 예전처럼 OnCommandGet에 도달하므로, 계약 우선 구간이 직접 작성한 라우트, DocumentRoot의 정적 콘텐츠와 한 포트 위에서 나란히 공존합니다.
포트, 바인딩, 인증서, HTTP/2 협상은 모두 호스트 서버에 속하므로 REST 표면은 이를 그대로 물려받습니다. TsgcHTTPRESTServer에 연결하면 그 서버의 CORS, 메트릭, 헬스 체크, 테넌시도 함께 적용됩니다.
버전 관리되고 계약으로 테스트되며, 고객이 /openapi.json에서 다운로드할 수 있는 자동 생성 SDK 제공.
리팩토링에서도 살아남는 서비스 간 계약 — 스펙이 곧 통합 테스트입니다.
동일한 Delphi 바이너리에서 문서화된 REST 제어 평면과 MQTT 또는 WebSocket 텔레메트리 표면을 함께 노출하는 엣지 디바이스.
각 공급자의 웹훅 페이로드가 타입화된 Pascal 레코드가 됩니다 — Stripe, GitHub, Twilio, Slack — 검증과 멱등성이 기본 내장됩니다.
비즈니스 로직을 다시 작성하지 않고도 오래된 DataSnap 또는 RemObjects 백엔드를 깔끔한 OpenAPI 표면 뒤로 감싸세요.
두세 개의 업스트림 API를 소비자에 맞춘 하나의 스펙 뒤로 집계하세요 — SPA나 모바일 앱은 단일 타입 엔드포인트와 대화합니다.
외부 스펙을 서버가 사용하는 동일한 모델에 로드하세요 — 동일한 검증, 동일한 타입 시스템, 동일한 보안 프리미티브.
AWS, Azure, GCP, Stripe, GitHub, Kubernetes 등을 위한 1,195개 이상의 생성된 SDK — 서버는 동일한 컴포넌트 패밀리로 이들 중 어느 것이든 호출할 수 있습니다.
WebSocket, MQTT, AMQP, WebRTC, AI/LLM, IoT — HTTP 서버가 REST 표면과 나란히 호스팅할 수 있는 모든 것.
규제 산업을 위해 XAdES / PAdES / CAdES로 요청 및 응답 본문에 서명하세요 — 모든 작업에 eIDAS급 무결성.