mcpField
W
writing-json-schemas

writing-json-schemas

github.com/zaggino開発349272 回インストール5 日前に更新
リポジトリ

writing-json-schemas について

writing-json-schemas は、z-schema での検証を想定した、慣用的な JSON Schema の作成を支援するスキルです。構造や制約、合成、参照、ドラフト別の実践方法を扱い、draft-2020-12 を標準の対象とします。

主な機能

  1. 01draft-2020-12 のスキーマテンプレート
  2. 02オブジェクトと配列の制約
  3. 03コンビネーターと条件付きスキーマ
  4. 04再利用可能な定義と参照
  5. 05プロパティを厳密に扱う指針

活用シーン

  1. 01アプリケーションデータのスキーマ定義
  2. 02allOf と $defs によるスキーマ合成
  3. 03draft-2020-12 のタプル構文の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/zaggino/z-schema --skill writing-json-schemas

インストール後、Claude Code で/writing-json-schemasを入力して読み込まれたか確認します。

詳細

z-schema 用 JSON Schema の作成

z-schema で検証される、正しく慣用的な JSON Schema を作成します。デフォルトの対象は draft-2020-12 です。

スキーマテンプレート

すべてのスキーマは、$schema 宣言と type から始めます。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {},
  "required": [],
  "additionalProperties": false
}

余分なプロパティを拒否する場合は、additionalProperties: false を明示的に設定します。z-schema では、デフォルトで余分なプロパティが許可されます。

オブジェクトスキーマ

必須フィールドを持つ基本的なオブジェクト
{
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1 },
    "email": { "type": "string", "format": "email" },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}
ネストされたオブジェクト
{
  "type": "object",
  "properties": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" }
      },
      "required": ["street", "city"]
    }
  }
}
動的なプロパティ名

patternProperties を使用して、正規表現でプロパティキーを検証します。

{
  "type": "object",
  "patternProperties": {
    "^x-": { "type": "string" }
  },
  "additionalProperties": false
}

propertyNames(draft-06 以降)を使用して、すべてのプロパティキー文字列に制約を設定します。

{
  "type": "object",
  "propertyNames": { "pattern": "^[a-z_]+$" }
}

配列スキーマ

均一な配列
{
  "type": "array",
  "items": { "type": "string" },
  "minItems": 1,
  "uniqueItems": true
}
タプルの検証(draft-2020-12)

位置ごとの型には prefixItems を使用し、残りの要素には items を使用します。

{
  "type": "array",
  "prefixItems": [{ "type": "string" }, { "type": "integer" }],
  "items": false
}

items: false は、タプルの位置を超える余分な要素を拒否します。

Contains(draft-06 以降)

一致する項目が少なくとも 1 つあることを必須にします。

{
  "type": "array",
  "contains": { "type": "string", "const": "admin" }
}

件数制約を設定する場合(draft-2019-09 以降):

{
  "type": "array",
  "contains": { "type": "integer", "minimum": 10 },
  "minContains": 2,
  "maxContains": 5
}

文字列の制約

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255,
  "pattern": "^[A-Za-z0-9_]+$"
}
フォーマット検証

z-schema には、date、date-time、time、email、idn-email、hostname、idn-hostname、ipv4、ipv6、uri、uri-reference、uri-template、iri、iri-reference、json-pointer、relative-json-pointer、regex、duration、uuid の組み込みフォーマットバリデーターがあります。

{ "type": "string", "format": "date-time" }

フォーマットアサーションは、デフォルトで常に適用されます(formatAssertions: null)。draft-2020-12 でボキャブラリーに応じた動作を有効にするには、バリデーターに formatAssertions: true を設定します。

数値の制約

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "multipleOf": 0.01
}

厳密な範囲制約には exclusiveMinimum / exclusiveMaximum を使用します。

{ "type": "integer", "exclusiveMinimum": 0, "exclusiveMaximum": 100 }

コンビネーター

anyOf — 少なくとも 1 つに一致
{
  "anyOf": [{ "type": "string" }, { "type": "number" }]
}
oneOf — ちょうど 1 つに一致
{
  "oneOf": [
    { "type": "string", "maxLength": 5 },
    { "type": "string", "minLength": 10 }
  ]
}
allOf — すべてに一致

スキーマの合成に使用します。基本スキーマに追加の制約を組み合わせます。

{
  "allOf": [{ "$ref": "#/$defs/base" }, { "properties": { "extra": { "type": "string" } } }]
}
not — 一致してはならない
{ "not": { "type": "null" } }
if / then / else(draft-07 以降)

条件付き検証です。「X の場合は Y を必須にする」というロジックには、複雑な oneOf よりこちらを推奨します。

{
  "type": "object",
  "properties": {
    "type": { "type": "string", "enum": ["personal", "business"] },
    "company": { "type": "string" }
  },
  "if": { "properties": { "type": { "const": "business" } } },
  "then": { "required": ["company"] },
  "else": {}
}
コンビネーターの使い分け
シナリオ使用するもの
値が複数の型になり得るanyOf
ちょうど 1 つのバリアントに一致する必要があるoneOf
継承されたスキーマを合成するallOf
「条件を満たす場合にフィールドを必須にする」if/then/else
特定の形状を除外するnot

条件が単一の識別フィールドの場合は、oneOf よりも if/then/else を推奨します。エラーメッセージがより明確になります。

$ref と $defs を使ったスキーマの再利用

ローカル定義
{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      },
      "required": ["street", "city"]
    }
  },
  "type": "object",
  "properties": {
    "home": { "$ref": "#/$defs/address" },
    "work": { "$ref": "#/$defs/address" }
  }
}
スキーマ間の参照

スキーマの配列をコンパイルし、ID で参照します。

import ZSchema from 'z-schema';

const schemas = [
  {
    $id: 'address',
    type: 'object',
    properties: { city: { type: 'string' } },
    required: ['city'],
  },
  {
    $id: 'person',
    type: 'object',
    properties: {
      name: { type: 'string' },
      home: { $ref: 'address' },
    },
    required: ['name'],
  },
];

const validator = ZSchema.create();
validator.validateSchema(schemas);
validator.validate({ name: 'Alice', home: { city: 'Paris' } }, 'person');

unevaluatedProperties を使った厳密なスキーマ(draft-2019-09 以降)

スキーマを allOf で組み合わせると、サブスキーマの additionalProperties: false によって、兄弟スキーマで定義されたプロパティがブロックされます。代わりに unevaluatedProperties を使用してください。適用キーワード全体で評価されたすべてのプロパティを追跡できます。

{
  "allOf": [
    {
      "type": "object",
      "properties": { "name": { "type": "string" } },
      "required": ["name"]
    },
    {
      "type": "object",
      "properties": { "age": { "type": "integer" } }
    }
  ],
  "unevaluatedProperties": false
}

これにより { "name": "Alice", "age": 30 } は受け入れられますが、{ "name": "Alice", "age": 30, "extra": true } は拒否されます。

スキーマ自体の検証

起動時に必ずスキーマを検証します。

const validator = ZSchema.create();
try {
  validator.validateSchema(schema);
} catch (err) {
  console.log('Schema errors:', err.details);
}

よくある間違い

  • additionalProperties の指定漏れ:デフォルトでは余分なプロパティが許可されます。拒否するには additionalProperties: false を設定するか、unevaluatedProperties: false を使用します。
  • allOf と additionalProperties: false の併用:兄弟スキーマのプロパティがブロックされます。代わりにトップレベルで unevaluatedProperties: false を使用します(draft-2019-09 以降)。
  • draft-2020-12 での配列の items:タプルの検証には prefixItems を使用します。items は現在、「残りの項目に対するスキーマ」を意味します。
  • $schema の指定漏れ:指定がない場合、z-schema は設定されたデフォルトのドラフトを使用します。対象のドラフトを明示するには $schema を含めます。
  • definitions と $defs の違い:どちらも機能しますが、draft-2019-09 以降では $defs が標準形式です。一貫して使用してください。

コメント