Delphi 用 OpenAPI サーバー
TsgcWSAPIServer_OpenAPI は、読み込んだ OpenAPI 3.x ドキュメントを配信し、受信するすべてのリクエストをそのドキュメントと照合し、ハンドラーが動く前にリクエストを検証し、同じポートからドキュメントと Swagger UI ページを公開します。1 つの Delphi コンポーネントを TsgcHTTPServer にアタッチするだけです。
TsgcWSAPIServer_OpenAPI は、読み込んだ OpenAPI 3.x ドキュメントを配信し、受信するすべてのリクエストをそのドキュメントと照合し、ハンドラーが動く前にリクエストを検証し、同じポートからドキュメントと Swagger UI ページを公開します。1 つの Delphi コンポーネントを TsgcHTTPServer にアタッチするだけです。
OpenAPI ドキュメントを、稼働中で検証済み、自己文書化された REST サーバーに変える 1 つの Delphi コンポーネント。
TsgcWSAPIServer_OpenAPI。sgcWebSocket_Server_API_OpenAPI で宣言されています
Server に TsgcHTTPServer、TsgcHTTPRESTServer、または TsgcWebSocketHTTPServer を割り当てます。ポート、バインディング、TLS はホストが管理します。
OpenAPI 3.0 と 3.1 のドキュメントを、LoadFromFile と LoadFromString で JSON として読み込みます
すでに手元にあるドキュメントから始めるスペックファースト、または属性付きの Delphi クラスから始めるコードファースト。コードファーストには 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 は、オペレーション 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 の応答はコンポーネントが行います。
スキームが宣言するとおりに、ヘッダー、クエリパラメータ、または cookie から読み取ります。OnValidateAPIKey はスキーム、名前、位置、キーを受け取り、Valid で応答します。
Authorization ヘッダーは自動で解析されます。OnValidateBasic はユーザー名とパスワードを受け取り、Valid で応答します。資格情報がログに書き込まれることはありません。
Security.JWTSecret がトークンを検証します。HMAC シークレットはそのまま使われ、-----BEGIN を含む値は PEM 公開鍵として扱われます。ValidateExpiration、Issuer、Audience がクレームをチェックします。
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 がオンのときに配信します。サーバーが実際にルーティングしている内容と常に一致します。任意のクライアントジェネレータをこの URL に向けられます。sgcOpenAPI も含めて。
インタラクティブな Swagger UI ページを、Endpoint.ServeSwaggerUI がオンのときに配信します。オペレーションを試し、スキーマを閲覧し、例を読めます。すべて実際に稼働しているサーバーから供給されます。
ページは既定で公開 CDN から CSS と JavaScript を読み込みます。Endpoint.SwaggerUIBaseURL でバージョンを固定でき、Endpoint.SwaggerUIAssetsPath を使えば swagger-ui.css と swagger-ui-bundle.js をローカルフォルダから配信できるので、外部ネットワークに接続できないマシンでも動作します。
5 つの永続的なサブオブジェクトで、すべてオブジェクトインスペクターに表示され、すべて実行時に割り当てられます。
BasePath は、すべてのルートと 2 つの組み込みエンドポイントの両方にプレフィックスを付けます。ServeSpec と ServeSwaggerUI でそれぞれを切り替えます。SpecFile は、どちらでもない最初のリクエストの時点で遅延読み込みされるため、ドキュメントを最初の呼び出しから確実に用意しておきたい場合は LoadFromFile を使ってください。
ValidateRequest と、5 つの範囲スイッチ、そして 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 サーバーにアタッチします。ポート 1 つ、TLS 証明書 1 つ、ログストリーム 1 つ。
Active プロパティはありません。Server を割り当てるとコンポーネントがアタッチされ、nil を設定するとデタッチされます。どちらの場合もホストサーバーは動作し続けます。デタッチされると、そのドキュメントが所有するパスはそのまま通常のハンドラーに通ります。
各リクエストはまずコンポーネントに提示され、コンポーネントはそのドキュメントが宣言するパスにのみ応答します。それ以外はすべて従来どおり OnCommandGet に届くため、コントラクトファーストの区画は、手書きのルートや DocumentRoot の静的コンテンツと同じポート上で共存できます。
ポート、バインディング、証明書、HTTP/2 ネゴシエーションはホストサーバーに属しているため、REST 面はそれらをそのまま引き継ぎます。TsgcHTTPRESTServer にアタッチすれば、そのサーバーの CORS、メトリクス、ヘルス、テナンシーも適用されます。
バージョン管理、コントラクトテスト済み、自動生成された SDK は顧客が /openapi.json からダウンロードできます。
リファクタを生き延びるサービス間コントラクト — 仕様がそのまま統合テストです。
エッジデバイスが、同一の Delphi バイナリから、ドキュメント化された REST コントロールプレーンと MQTT または WebSocket のテレメトリ面を公開します。
各プロバイダの Webhook ペイロードが型付きの Pascal レコードになります — Stripe、GitHub、Twilio、Slack — 検証と冪等性が標準装備。
ビジネスロジックを書き直さずに、古い DataSnap や RemObjects のバックエンドをきれいな OpenAPI 面の背後に包み込みます。
2、3 個のアップストリーム API を、消費者の形に合わせた 1 つの仕様の背後に集約 — SPA やモバイルアプリは型付きの単一エンドポイントと対話します。
あらゆる外部仕様を、サーバーが使うのと同じモデルにロードできます — 同じ検証、同じ型システム、同じセキュリティのプリミティブ。
AWS、Azure、GCP、Stripe、GitHub、Kubernetes など向けの 1,195 以上の生成済み SDK — サーバーは同じコンポーネントファミリーで、そのいずれも呼び出せます。
WebSocket、MQTT、AMQP、WebRTC、AI/LLM、IoT — HTTP サーバーが REST 面と並べてホストできるすべて。
規制業界向けに、リクエストおよびレスポンスのボディに XAdES / PAdES / CAdES で署名 — どのオペレーションにも eIDAS グレードの完全性。