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. 02使用 allOf 和 $defs 组合架构
  3. 03选择 draft-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 模板

每个 Schema 都以 $schema 声明和 type 开头:

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

当需要拒绝额外属性时,显式设置 additionalProperties: false——z-schema 默认允许额外属性。

对象 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_]+$" }
}

数组 Schema

统一类型的数组
{
  "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+)

要求至少有一个匹配项:

{
  "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 — 至少匹配一个
{
  "anyOf": [{ "type": "string" }, { "type": "number" }]
}
oneOf — 恰好匹配一个
{
  "oneOf": [
    { "type": "string", "maxLength": 5 },
    { "type": "string", "minLength": 10 }
  ]
}
allOf — 全部匹配

用于组合 Schema。将基础 Schema 与细化规则组合:

{
  "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
必须恰好匹配一个变体oneOf
组合继承的 SchemaallOf
“如果满足条件,则要求字段”if/then/else
排除特定结构not

当条件是单个判别字段时,优先使用 if/then/else,而不是 oneOf——这样会生成更清晰的错误消息。

使用 $ref 和 $defs 复用 Schema

本地定义
{
  "$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" }
  }
}
跨 Schema 引用

编译一个 Schema 数组,并通过 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 编写严格 Schema(draft-2019-09+)

使用 allOf 组合 Schema 时,子 Schema 中的 additionalProperties: false 会阻止兄弟 Schema 中定义的属性。改用 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 }。

验证 Schema 本身

始终在启动时验证 Schema:

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

常见错误

  • 忘记设置 additionalProperties:默认情况下允许额外属性。设置 additionalProperties: false 或使用 unevaluatedProperties: false 来拒绝它们。
  • 在 allOf 中使用 additionalProperties: false:这会阻止兄弟 Schema 中的属性。请改为在顶层设置 unevaluatedProperties: false(draft-2019-09+)。
  • draft-2020-12 中数组的 items:元组验证请使用 prefixItems。现在 items 表示“剩余元素的 Schema”。
  • 缺少 $schema:如果没有它,z-schema 会使用配置的默认草案。请包含 $schema,以明确指定目标草案。
  • definitions 与 $defs:两者都可用,但 $defs 是 draft-2019-09+ 中的规范形式。请保持一致。

评论

支持 Markdown