🔍 スキーマ
スキーマは、受信リクエストデータの形状を定義・検証します。Nodeblocks は JSON Schema Draft-07 に依存し、AJV で実行時検証します。スキーマは withSchema プリミティブで定義します。
スキーマ登録 API はありません。withSchema は ServiceDefinition を変換する SchemaComposer を返します。スキーマは src/schemas/ からエクスポートされ、compose(schema, route) によって機能内のルートと対になります。
単一の名前空間エクスポートを使用してスキーマをインポートします。
import { schemas } from '@nodeblocks/backend-sdk';
🔍 スキーマとは
withSchema は、(service: ServiceDefinition) => ServiceDefinition という関数の SchemaComposerWithSchema を返します。これは service.withNextRoute を設定します。このフックは withRoute が次のルートを登録するとき、その次のルートハンドラーを検証でラップします。
スキーマのライフサイクル
schemas/*.ts → features/*.ts → services/*.ts → defService()
(withSchema) (スキーマ + ルートを合成) (提供)
- 定義 —
src/schemas/<domain>.tsからwithSchema(...)をエクスポート - ルートと対にする —
src/features/<domain>.tsでcompose(schema, route)(スキーマを先に置く必要があります) - バンドル — サービスファクトリー内で機能を結合
- 提供 —
defServiceでマウント
スキーマがルートへ付加される方法は Feature » と Route » を参照してください。
HTTP ルートでは、スキーマ検証はラップされたハンドラー内でビジネスロジックの前に実行されます。無効な HTTP リクエストはステータス 400 の NodeblocksError をスローします。レガシー JSON Schema コンポーザーは WebSocket メッセージ検証もサポートしますが、OpenAPI コンポーザーは HTTP ルート用です。
📐 スキーマとバリデーター
ハンドラーロジックより前に 2 層が実行されます。
| 層 | 目的 | 定義方法 |
|---|---|---|
| スキーマ | リクエスト形状(パス、クエリ、本文フィールド)を検証 | 機能内の withSchema |
| バリデーター | ビジネスロジック検査(認証、存在、権限) | withRoute の validators |
スキーマ検証は、ルート登録時に withNextRoute により注入されます。ルートバリデーターはハンドラーチェーンの前に defService で個別に実行されます。スキーマ検証を超えるビジネスロジック検査については Validator » を参照してください。
📐 OpenAPI モード(推奨)
parameters および/または requestBody を持つ OpenAPI 操作オブジェクトを渡します。SDK スキーマの主なパターンです。
import { primitives } from '@nodeblocks/backend-sdk';
const { withSchema } = primitives;
export const identityIdPathParameter: primitives.OpenAPIParameter = {
in: 'path',
name: 'identityId',
required: true,
schema: { type: 'string' },
};
export const getIdentitySchema = withSchema({
parameters: [{ ...identityIdPathParameter }],
});
export const updateIdentitySchema = withSchema({
parameters: [{ ...identityIdPathParameter }],
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
additionalProperties: false,
properties: {
email: { type: 'string' },
emailVerified: { type: 'boolean' },
typeId: { type: 'string' },
},
},
},
},
required: true,
},
});
identityIdPathParameter のような再利用可能パラメーター定数は、ドメインモジュール内のスキーマ間で共有されます。
OpenAPI 検証範囲
| 動作 | 詳細 |
|---|---|
| 対応する場所 | path と query のみ。params.requestParams/params.requestQuery から読み取ります。 |
| ヘッダー/Cookie パラメーター | OpenAPIParameter 型には header と cookie がありますが、バリデーターはヘッダーも Cookie も読み取りません。withSchema によるヘッダー検証には依存しないでください。 |
| パスパラメーター | 常に必須として扱われます。 |
| クエリの厳格性 | 未定義のクエリキーは拒否されます(query parameter 'X' is not allowed)。 |
| リクエスト本文 | POST、PUT、PATCH、DELETE でのみ検証され、GET では検証されません。 |
| コンテンツタイプ | デフォルトは application/json で、最初の content エントリーへフォールバックします。 |
| WebSocket ルート | WebSocket メッセージ検証にはレガシー JSON Schema モードを使用します。OpenAPI モードは HTTP ルート用です。 |
📐 レガシー JSON Schema モード
JSON Schema オブジェクト(またはマージする複数スキーマ)を渡して、リクエスト本文のみを検証します。
export const createItemSchema = withSchema({
type: 'object',
additionalProperties: false,
properties: {
name: { type: 'string' },
status: { type: 'string' },
},
required: ['name', 'status'],
});
複数の JSON Schema 引数を渡すと深くマージされます。
withSchema(baseSchema, extensionSchema);
レガシー WebSocket サポート
レガシーコンポーザーは、protocol: 'ws' ルートの受信 WebSocket メッセージを検証します。バリデーターは、メッセージをスキーマと照合する前に、defService が追加した emitterId を削除します。OpenAPI モードは WebSocket 検証をサポートしません。
📋 フィールド要件
required 配列は、存在しなければならないプロパティを決定します。
withSchema({
type: 'object',
properties: {
productId: { type: 'string' },
rating: { type: 'number', minimum: 1, maximum: 5 },
},
required: ['productId', 'rating'],
});
OpenAPI リクエスト本文では、本文自体が必須の場合に requestBody オブジェクトで required: true を設定します。
🔒 デフォルトスキーマ拡張
SDK は、オブジェクトスキーマに applyDefaultSchemaEnhancements を再帰的に適用します。
additionalProperties: false— オーバーライドしない限り未定義フィールドをブロックqueryFilter: true— ネストしたオブジェクトスキーマで MongoDB インジェクションから保護
withSchema({
type: 'object',
additionalProperties: true, // 追加フィールドを明示的に許可
properties: {
name: { type: 'string' },
},
});
⚠️ 検証エラー
検証に失敗すると、ハンドラー実行前に withSchema は NodeblocksError(400, 'Validation Error', 'withSchema', errors) をスローします。
OpenAPI モード — 場所を接頭辞にしたメッセージです。
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'email'",
"path parameter 'identityId' is required",
"query parameter 'page' is not allowed"
]
}
}
レガシーモード — リクエスト本文のみを検証します。エラーメッセージは request body 接頭辞なしの未加工 AJV 出力です(例: "must have required property 'name'")。
🔧 スキーマ定義を読み取る
getSchemaDefinition(レガシーのみ)
import { primitives } from '@nodeblocks/backend-sdk';
const { getSchemaDefinition } = primitives;
const merged = getSchemaDefinition(legacySchemaComposer);
.schema プロパティを公開するレガシー JSON Schema コンポーザーでのみ動作します。OpenAPI コンポーザーで呼び出すとスローされます。代わりに schemaComposer.openapi を読んでください。
📦 SDK スキーマモジュール
スキーマは SDK の schemas 名前空間でドメイン別に整理され、src/schemas/index.ts と対応しています。
| モジュール | 説明 | リファレンス |
|---|---|---|
| Address | 住所検索スキーマ | SDK のみ — ドキュメント準備中 |
| Attributes | 属性管理スキーマ | Attribute スキーマ » |
| Authentication | 認証およびトークンスキーマ | Authentication スキーマ » |
| Avatar | アバター構造スキーマ | Avatar スキーマ » |
| Category | カテゴリ CRUD スキーマ | Category スキーマ » |
| Chat | チャットチャンネルおよびメッセージスキーマ | Chat スキーマ » |
| Common | 共通スキーマ(ページネーションなど) | ドメイン間で使用 |
| File Storage | ファイルアップロードスキーマ | File Storage スキーマ » |
| Identity | アイデンティティライフサイクルスキーマ | Identity スキーマ » |
| Invitation | 招待スキーマ | Invitation スキーマ » |
| Location | 場所管理スキーマ | Location スキーマ » |
| Notification | 通知スキーマ | SDK のみ — ドキュメント準備中 |
| OAuth | OAuth フロースキーマ | OAuth スキーマ » |
| Order | 注文管理スキーマ | Order スキーマ » |
| Organization | 組織スキーマ | Organization スキーマ » |
| Product | プロダクト管理スキーマ | Product スキーマ » |
| Profile | プロフィールスキーマ | Profile スキーマ » |
➡️ 次
ビジネスロジック検査については Validator »、スキーマとルートの対については Feature »、ハンドラーチェーンについては Route » を確認してください。