We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
site: https://tour.json-schema.org/ repo: https://github.com/json-schema-org/tour
{ "name": "John Doe", "age": 25 }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } } }
嵌套对象
{ "name": { "firstName": "John", "lastName": "Doe", "middleName": "Smith" } "age": 25, }
{ "type": "object", "properties": { "name": { "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "middleName": { "type": "string" } } }, "age": { "type": "integer" } } }
{ "type": "object", "properties": { "name": { "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "middleName": { "type": "string" } }, "required": ["firstName", "lastName"] }, "age": { "type": "integer" } } }
{ "name": "John Doe", "age": 25, "hobbies": "reading" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "hobbies": { "type": "string", "enum": ["reading", "writing", "painting"] } } }
{ "name": "John Doe", "age": 25, "hobbies": ["reading", "writing"] }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "hobbies": { "type": "array", "items": { "type": "string" } } }, "required": ["name", "age", "hobbies"] }
{ "name": "John Doe", "age": 25, "skills": [ { "name": "JavaScript", "level": "beginner" }, { "name": "React", "level": "intermediate" } ] }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "skills": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "level": { "type": "string" } } } } } }
{ "name": "John Doe", "age": 25, "postalCode": "385004", "phoneNumber": "84584898564" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "phoneNumber": { "type": "string", "minLength": 10, "maxLength": 10 }, "postalCode": { "type": "string", "minLength": 6, "maxLength": 6 } } }
{ "name": "John Doe", "age": 25, "postalCode": "385004", "phoneNumber": "84584898564", "countryCode": "IN" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "postalCode": { "type": "string", "pattern": "^[0-9]{6}$" }, "phoneNumber": { "type": "string", "pattern": "^[0-9]{10}$" }, "countryCode": { "type": "string", "pattern": "^[A-Z]{2}$" } } }
^
[0-9]
{6}
$
{ "name": "John Doe ", "age": 25, "dateOfBirth": { "day": 1, "month": 1, "year": 1995 } }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "minimum": 18, "maximum": 60 }, "dateOfBirth": { "type": "object", "properties": { "year": { "type": "integer", "minimum": 1964, "maximum": 2024 }, "month": { "type": "integer", "minimum": 1, "maximum": 12 }, "day": { "type": "integer", "minimum": 1, "maximum": 31 } } } } }
integer 表示整数类型
{ "name": "John Doe", "age": 25, "salary": 50000 }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "exclusiveMinimum": 18, "exclusiveMaximum": 60 }, "salary": { "type": "integer", "exclusiveMinimum": 30000, "exclusiveMaximum": 80000 } } }
exclusiveMinimum 表示 x 大于某值,x > exclusiveMinimum
exclusiveMinimum
x > exclusiveMinimum
exclusiveMaximum 表示 x 小于某值, x < exclusiveMaximum
exclusiveMaximum
x < exclusiveMaximum
{ "name": "John Doe", "age": 25, "hourlyWage": 10 }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "hourlyWage": { "type": "number", "multipleOf": 0.25, "minimum": 0, "maximum": 100 } } }
hourlyWage 是 0.25 的倍数,且 hourlyWage 最小值为 0 ,最大值为 100
{ "name": "John Doe", "age": 25, "performanceRating": 4.5 }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "performanceRating": { "type": "number", "minimum": 0, "maximum": 5 } } }
PerformanceRating 属性接受最小值为 0 、最大值为 5 的十进制数字, 可以是小数
{ "name": "John Doe", "age": 25, "performanceRating": 4 }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "performanceRating": { "enum": [1, 2, 3, 4, 5, null] } } }
以前,我们只对字符串使用枚举值。但是,您也可以将它们用于任何类型,包括数字和空值。
{ "name": "John Doe", "age": 25, "companyName": "MyCompany" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "const": 25 }, "companyName": { "const": "MyCompany" } } }
companyName 是一个常量值 MyCompany, age 为常量 25
MyCompany
{ "name": "John Doe", "age": 25, "hasAgreedToTerms": true }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "hasAgreedToTerms": { "type": ["boolean", "null"] } } }
可以通过将类型数组传递给 type 字段来定义多个类型
hasAgreedToTerms 属性接受布尔值和空值
{ "name": "John Doe", "age": 25, "DEPT-001": "HR" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } }, "patternProperties": { "^DEPT-[0-9]{3}$": { "pattern": "^[A-Z]+$" } }, "additionalProperties": false }
这就是 patternProperties 发挥作用的地方:它将正则表达式映射到模式。如果属性名与给定的正则表达式匹配,则属性值必须针对相应的模式进行验证。
提示: 使用 patternProperties 关键字定义属性名称的模式,使用 pattern 关键字定义属性值的模式。您可以将模式设置为 ^[ A-Z ]+$ 以匹配所有大写字母。
patternProperties
pattern
^[ A-Z ]+$
将 addtionalProperties 设置为 false 以禁止任何其他属性。我们将在下一课中学习更多关于附加属性的知识。
addtionalProperties
{ "type": "object", "properties": { "name": {...}, "age": {...} }, "additionalProperties": false }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } }, "additionalProperties": { "type": "integer" } }
默认情况下,允许任何附加属性。如果将 additionalProperties 设置为 false 可以禁止任何附加属性。
可以将 addtionalProperties 设置为一个 schema,以为其他属性定义 schema
{ "name": "John Doe", "age": 25, "contactMethods": { "email": "jhon.doe@MyCompany.com", "phone": "1234567890", "mobile": "0987654321" } }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "contactMethods": { "type": "object", "minProperties": 2, "maxProperties": 5, "additionalProperties": { "type": "string" } } } }
现在,将 minProperties 和 maxProperties 关键字添加到侧编辑器上的模式中,以设置 contactMethods 对象中属性的最小和最大数量。
此外,在 contactMethod 对象中,使用 addtionalProperties 关键字确保属性的值是字符串类型。
{ "type": "object", "propertyNames": { "pattern": "^[A-Z]+$" } }
对象应该至少有 2 个属性。
属性名称应以大写字母书写,并且长度应至少为 3 个字符。
属性值应该是字符串或整数。
{ "type": "object", "minProperties": 2, "propertyNames": { "pattern": "^[A-Z]{3,}$" }, "additionalProperties": { "type": ["string", "integer"] } }
{ "name": "John Doe", "age": 25, "phones": ["123-456-7890", "987-654-3210"] }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "phones": { "type": "array", "items": { "type": "string", "pattern": "^\\d{3}-\\d{3}-\\d{4}$" }, "minItems": 1, "maxItems": 3 } } }
phones 属性,并将最小项指定为 1,最大项指定为 3。另外,将电话号码的格式限制为 xxx-xxx-xxxx。
提示:使用正则表达式^\\d{3}-\\d{3}-\\d{4}$和 pattern 关键字来验证电话号码格式。
^\\d{3}-\\d{3}-\\d{4}$
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "phones": { "type": "array", "items": { "type": "string", "pattern": "^\\d{3}-\\d{3}-\\d{4}$" }, "uniqueItems": true } } }
{ "name": "John Doe", "age": 25, "address": [123, "Main St", "Avenue", "NW"] }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "address": { "type": "array", "prefixItems": [ { "type": "integer" }, { "type": "string" }, { "type": "string", "enum": ["Street", "Avenue", "Boulevard"] }, { "type": "string", "enum": ["NW", "NE", "SE", "SW"] } ] } } }
在这种情况下,可以使用 prefixItems 关键字为元组数组的每个元素定义模式。
Example
{ "type": "array", "prefixItems": [{ "type": "integer" }, { "type": "string" }] }
上面的模式定义了一个数组,其中第一个元素应该是整数,第二个元素应该是字符串。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "address": { "type": "array", "items": { "type": ["string"] }, "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ] } } }
可以将 items 关键字设置为 false,以禁止在元组数组中添加其他项.
提示:向 items 关键字添加一个子 schame,以定义附加项的 schema。
{ "name": "John Doe", "age": 25, "relevantDepartments": ["HR", "Finance"] }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "relevantDepartments": { "type": "array", "items": { "enum": ["HR", "Finance", "IT", "Admin"] }, "uniqueItems": true } } }
前面,我们使用 enum 来限制字符串属性的值。类似地,可以使用 enum 关键字限制数组项的值。
在下面的示例中,我们有一个验证数字数组的 JSON Schema。该模式确保数组至少包含一个小于 10 的元素。
{ "type": "array", "contains": { "type": "number", "maximum": 10 } }
现在,我们要确保 skills 数组至少包含一个等于“JavaScript”的元素。
提示:使用 const 关键字指定 JavaScript 作为必需的元素。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "skills": { "type": "array", "contains": { "type": "string", "const": "JavaScript" } } }, "required": ["name", "age", "skills"] }
下面的示例演示了如何使用 minContains 和 maxContains 关键字来确保数组恰好包含 2 个小于 10 的元素。
{ "type": "array", "contains": { "type": "number", "maximum": 10 }, "minContains": 2, "maxContains": 2 }
我们的员工有工作时间。我们要确保 workedHours 数组至少包含两个大于或等于 8 且小于或等于 12 的元素。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "workedHours": { "type": "array", "contains": { "type": "number", "minimum": 8, "maximum": 12 }, "minContains": 2 } } }
我们已经定义了带有 prefixItems 的数组项。当项目多于定义的 prefixItems 时,可以使用 unevaluatedItems 为其余项目定义子模式。
{ "type": "array", "prefixItems": [{ "type": "number" }, { "type": "string" }], "unevaluatedItems": { "type": "number" } }
在这种情况下,前两个项由 prefixItems 计算,其余项由 unevaluatedItems 计算。
Task
前三个元素只能有“HTML”、“CSS”和“JavaScript”作为值(以任何顺序),不能有其他任何值。
其余元素为字符串类型。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "skills": { "type": "array", "prefixItems": [ { "type": "string", "enum": ["HTML", "CSS", "JavaScript"] }, { "type": "string", "enum": ["HTML", "CSS", "JavaScript"] }, { "type": "string", "enum": ["HTML", "CSS", "JavaScript"] } ], "unevaluatedItems": { "type": "string" } } } }
什么是条件验证?
条件验证涉及根据 JSON 文档中其他属性的存在与否应用验证规则。
例如:
dependentRequired
dependentSchemas
if-then-else
implications
{ "name": "John Doe", "creditCardNumber": "1234 5678 1234 5678", "address": "123 Main St" }
如果 creditCardNumber 属性存在,那么地址属性也必须存在。
{ "type": "object", "properties": { "name": { "type": "string" }, "creditCardNumber": { "type": "string" }, "address": { "type": "string" } }, "dependentRequired": { "creditCardNumber": ["address"] }, "required": ["name"] }
确保 creditCardNumber 和 address 是相互依赖的。
{ "type": "object", "properties": { "name": { "type": "string" }, "creditCardNumber": { "type": "string" }, "address": { "type": "string" } }, "dependentRequired": { "creditCardNumber": ["address"], "address": ["creditCardNumber"] }, "required": ["name"] }
当你希望基于属性的存在与否应用 subschema 时,可以使用 dependentSchemas 关键字。此关键字允许您定义仅在存在或不存在特定属性时应用的 subschema。
更新以确保如果存在 creditCardNumber 属性,那么使用 dependentSchemas 关键字也必须存在地址属性。
{ "type": "object", "properties": { "name": { "type": "string" }, "creditCardNumber": { "type": "string" } }, "dependentSchemas": { "creditCardNumber": { "properties": { "address": { "type": "string" } }, "required": ["address"] } }, "required": ["name"] }
{ "name": "John Doe", "isStudent": true, "age": 25 }
如果 isStudent 为真,则年龄字段必须存在。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "isStudent": { "type": "boolean" } }, "required": ["name"], "if": { "properties": { "isStudent": { "const": true } }, "required": ["isStudent"] }, "then": { "required": ["age"] } }
如果 isStudent 为真,则必须显示年龄字段,否则必须显示年级字段。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "isStudent": { "type": "boolean" }, "grade": { "type": "number", "minimum": 0, "maximum": 10 } }, "if": { "properties": { "isStudent": { "const": true } }, "required": ["isStudent"] }, "then": { "required": ["age"] }, "else": { "required": ["grade"] }, "required": ["name", "isStudent"] }
组合子模式
在本模块中,您将学习如何组合多个子模式来创建更复杂的 JSON 模式。您将学习以下关键字:allOf、anyOf、oneOf、not、$defs、$ref 和递归模式。
在 JSON Schema 中,$defs关键字允许您定义可重用的子模式。然后可以使用$ref 关键字引用这些子模式。
要用$defs 定义一个子模式,你可以使用以下语法:
$defs
{ "$defs": { "mySubschema": { "type": "string", "maxLength": 10 } } }
在上面的例子中,我们定义了一个名为 mySubschema 的子模式,它指定该值应该是一个最大长度为 10 个字符的字符串。
要使用$ref 来引用这个子模式,你可以使用以下语法:
$ref
{ "$ref": "#/$defs/mySubschema" }
在上面的例子中,我们使用$ref 来引用 mySubschema 子模式。这允许我们在需要时重用 mySubschema 的定义。
mySubschema
通过促进代码重用,使用$defs和$ref 可以帮助您的 JSON 模式更加模块化和可维护。
{ "name": { "firstName": "John", "middleName": "Smith", "lastName": "Doe" } }
在 schame 中定义名为 stringType 的子模式,它只是“type”:“string”,然后使用$ref 引用属性 firstName, middleName 和 lastName
“type”:“string”
{ "$defs": { "stringType": { "type": "string" } }, "type": "object", "properties": { "name": { "type": "object", "properties": { "firstName": { "$ref": "#/$defs/stringType" }, "middleName": { "$ref": "#/$defs/stringType" }, "lastName": { "$ref": "#/$defs/stringType" } } } }, "required": ["name"] }
$schema 在 JSON Schema 中, $schema 是一个字符串,定义了写入该 schema 的 JSON Schema 标准的版本。
$schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" }
在上面的示例中,架构是在 JSON Schema 草案 2020-12 中编写的。您可以在此处找到最新版本的 JSON Schema。
在本教程中,我们使用了 JSON Schema 草案 2020-12。
$id
$id 关键字是一个字符串,用于定义模式的 URI。
{ "$id": "https://example.com/person", "type": "object", "properties": { "name": { "type": "string" } } }
在上面的示例中,模式的 URI 为https://example.com/person。
https://example.com/person
模式 URI 可用于使用 $ref关键字从其他模式引用该模式。
{ "$ref": "https://example.com/person" }
我们定义了一个简单的模式,如下所示。
{ "$id": "https://example.com/string", "type": "string" }
在 schema 中使用 $ref 关键字在 name 属性中引用此模式。
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { "$ref": "https://example.com/string" }, "age": { "type": "integer" } } }
对所有子 schema(AND)有效
当您希望确保一个实例对所有子模式都有效时,可以使用 allOf 关键字。
您可以将 allOf 视为子模式之间的 AND 操作。如果其中一个子模式失败,则认为该实例无效。
allOf
{ "name": "John Doe" }
我们将创建两个子模式 1. minStringLength 和 2. 字母和数字,然后使用 name 属性中的 allOf 将它们组合起来。
1. minStringLength
2. 字母和数字
{ "$defs": { "minStringLength": { "minLength": 5 }, "alphaNumeric": { "pattern": "^[a-zA-Z0-9]*$" } }, "type": "object", "properties": { "name": { "type": "string", "allOf": [ { "$ref": "#/$defs/minStringLength" }, { "$ref": "#/$defs/alphaNumeric" } ] } } }
上面的模式确保 name 属性对 minStringLength 和 alphannumeric 子模式都有效。换句话说,name 属性的最小长度必须为 5 个字符,并且必须只包含字母数字字符。
注意:没有必要使用$defs和$ref 来定义子 schame。您也可以直接内联地定义子 schema。
定义一个内联子模式,检查 age 是否为整数类型
使用 age 属性中的 allOf 组合 ageLimit 和内联子模式。
{ "$defs": { "ageLimit": { "minimum": 18, "maximum": 60 } }, "type": "object", "properties": { "name": { "type": "string" }, "age": { "allOf": [ { "type": "integer" }, { "$ref": "#/$defs/ageLimit" } ] } }, "required": ["name"] }
验证对其中一个子 schema 有效
{ "name": "John Doe", "age": 25, "dateOfBirth": "1999-01-01" }
让我们向 JSON 文档添加一个新的属性 dateOfBirth:
现在要在文档中应用这些条件:
{ "type": "object", "properties": { ... "dateOfBirth": { "type": "string", "format": "date" } }, "oneOf": [ { "required": ["age"] }, { "required": ["dateOfBirth"] } ] }
在侧面编辑器中为上面的 JSON 文档提供了一个模式。使用 oneOf 关键字,更新模式以确保年龄符合以下条件之一:
提示: 使用最小 (minimum) 和最大关键字 (maximum) 来定义范围。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "oneOf": [{ "minimum": 18, "maximum": 60 }, { "minimum": 65 }] } } }
对任何子模式有效 (OR)
anyOf 关键字用于定义多个子模式。如果该实例对于任一子模式有效,则该文档被视为有效。
anyOf
{ "name": "John Doe", "age": 25, "dateOfBirth": "1995-12-17" }
我们希望在文档中允许使用“age”和“dateOfBirth”属性。如果文档具有 Age 或 dateOfBirth 属性,则该文档有效。我们可以使用 anyOf 关键字来定义这个条件。
{ "type": "object", "properties": {...}, "anyOf": [ {"required": ["age"]}, {"required": ["dateOfBirth"]} ] }
{ "name": "John Doe", "employeeType": "full-time", "salary": 50000, "hourlyRate": 25 }
要求:
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "employeeType": { "enum": ["full-time", "part-time"] } }, "anyOf": [ { "required": ["salary"] }, { "required": ["hourlyRate"] } ] }
反向验证
not关键字用于反转验证。如果实例对于子模式无效,则该文档被视为有效。
not
我们希望年龄大于或等于 18 岁。但不应该是 21 岁。我们可以使用 not 关键字来定义此条件。
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "minimum": 18, "not": { "const": 21 } } } }
{ "name": "John Doe", "age": 21, "status": "active" }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "status": { "not": { "type": "null" } } } }
递归架构
在 JSON 模式中,递归模式允许定义引用自身的模式。这在处理分层数据结构或建模递归关系时非常有用。
{ "name": "John Doe", "links": [ { "name": "Jane Doe", "links": [ { "name": "Alice Doe", "links": [] } ] }, { "name": "Jack Doe", "links": [] } ] }
要定义递归模式,可以使用 $ref 关键字引用模式本身:
{ "$defs": { "TreeNode": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "children": { "$ref": "#/$defs/TreeNode" } }, "required": ["name", "children"] } } }, "$ref": "#/$defs/TreeNode" }
在上面的示例中,TreeNode 架构在 children 属性中引用自己,从而创建一个递归结构。
{ "name": "John Doe", "next": { "value": "Jane Doe", "next": { "value": "Alice Doe", "next": {} } } }
使用递归模式定义 next schema:
{ "$defs": { "next": { "type": "object", "properties": { "value": { "type": ["string"] }, "next": { "oneOf": [ { "$ref": "#/$defs/next" }, { "type": "null" } ] } }, "required": ["next", "value"] } }, "type": "object", "properties": { "name": { "type": "string" }, "next": { "$ref": "#/$defs/next" } } }
扩展封闭的 schame
在前面的 Objects 模块中,我们学习了 addtionalProperties。但是,需要注意的是,addtionalProperties 只能识别在同一个子模式中声明的属性。
因此,addtionalProperties 可以限制您使用组合关键字(如 allOf)“扩展”模式。在下面的示例中,我们可以看到 addtionalProperties 如何导致扩展地址架构示例的尝试失败。
{ "allOf": [ { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"], "additionalProperties": false } ], "properties": { "type": { "enum": ["residential", "business"] } }, "required": ["type"] }
上述架构不允许您定义类型属性。因为 addtionalProperties 被设置为 false。原因是,addtionalProperties 只能识别在同一个子模式中声明的属性。
Unevaluated Properties
我们在 addtionalProperties 中看到的挑战可以使用 unevaluatedProperties 关键字来解决。此关键字允许您定义不由当前架构计算的属性。
{ "allOf": [ { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } ], "properties": { "type": { "enum": ["residential", "business"] } }, "unevaluatedProperties": false, "required": ["type"] }
将 unevaluatedProperties 添加到架构中,以允许将数字 number作为附加属性。
number
{ "allOf": [ { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } ], "properties": { "type": { "enum": ["residential", "business"] } }, "required": ["type"], "unevaluatedProperties": { "type": "number" } }
title 和 description 关键字用于提供人类可读的模式标题和描述。
这些关键字不用于验证,但工具和软件可以使用它们来提供关于模式的更多信息。
{ "type": "object", "title": "Person", "description": "A person in the system", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } } }
deprecated
布尔关键字 readOnly 和 writeOnly 通常用于 API 上下文中。
readOnly 表示该值不能修改。它可以用来指示更改值的 PUT 请求将导致 400 Bad request 响应。
readOnly
writeOnly 表示可以设置一个值,但将保持隐藏。它可用于指示您可以使用 PUT 请求设置一个值,但在使用 GET 请求检索该记录时不会包含它。
writeOnly
{ "type": "object", "properties": { "name": { "type": "string", "readOnly": true }, "age": { "type": "integer", "writeOnly": true } }, "deprecated": true }
要在 JSON Schema 中添加注释,请使用$comment关键字。$comment 关键字是一个字符串,它提供了关于模式的附加信息
$comment
可以使用 default 关键字为属性设置默认值。default 关键字用于为属性提供默认值。
default
{ "type": "object", "properties": { "name": { "type": "string", "$comment": "This is the name of the employee" }, "age": { "type": "integer", "default": 18 } } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
01-Getting-Started
01-Your-First-Schema
02-Nesting-Objects
03-Required-Properties
04-Enumerated-Values
05-Arrays
06-Array-of-Objects
02-Primitive-Types
01-Constraining-String-Length
02-Regular-Expressions-in-Strings
^
asserts the start of the string.[0-9]
matches any digit from 0 to 9.{6}
specifies that the previous pattern should be repeated exactly 6 times.$
asserts the end of the string.03-Constraining-Number
04-Exclusively-Constraining-Number
05-Multiple-of-a-Number
06-Decimal-Numbers
07-Enumerated Values II
以前,我们只对字符串使用枚举值。但是,您也可以将它们用于任何类型,包括数字和空值。
08-Defining-Constant-Values
09-Combining-Types
03-Objects
01-Pattern-Properties
02-Additional-Properties
03-Constraining-Number-of-Properties
04-Applying-Schema-to-Property-Names
对象应该至少有 2 个属性。
属性名称应以大写字母书写,并且长度应至少为 3 个字符。
属性值应该是字符串或整数。
04-Arrays
01-Specifying-Length-of-an-Array
02-Unique-Items
03-Tuple-Validation
Example
上面的模式定义了一个数组,其中第一个元素应该是整数,第二个元素应该是字符串。
04-Additional-Items-in-Tuples
05-Enumerated-Array-Items
06-Ensuring-Array-Content-With-Contains
在下面的示例中,我们有一个验证数字数组的 JSON Schema。该模式确保数组至少包含一个小于 10 的元素。
07-minContains-and-maxContains
下面的示例演示了如何使用 minContains 和 maxContains 关键字来确保数组恰好包含 2 个小于 10 的元素。
我们的员工有工作时间。我们要确保 workedHours 数组至少包含两个大于或等于 8 且小于或等于 12 的元素。
08-Unevaluated-Items
我们已经定义了带有 prefixItems 的数组项。当项目多于定义的 prefixItems 时,可以使用 unevaluatedItems 为其余项目定义子模式。
在这种情况下,前两个项由 prefixItems 计算,其余项由 unevaluatedItems 计算。
Task
前三个元素只能有“HTML”、“CSS”和“JavaScript”作为值(以任何顺序),不能有其他任何值。
其余元素为字符串类型。
05-Conditional-Validation
01-Ensuring-Conditional-Property-Presence
什么是条件验证?
条件验证涉及根据 JSON 文档中其他属性的存在与否应用验证规则。
例如:
dependentRequired
: 如果属性 a 存在,那么属性 B 必须存在。dependentSchemas
: 如果存在属性 a,则应用子模式 B。if-then-else
: 如果子模式 a 有效,则子模式 B 必须有效,否则子模式 C 必须有效。implications
: 如果子模式 A 是有效的,那么子模式 B 一定是有效的。Task
如果 creditCardNumber 属性存在,那么地址属性也必须存在。
02-Mutual Dependency
确保 creditCardNumber 和 address 是相互依赖的。
03-Conditionally-Apply-a-Subschema
当你希望基于属性的存在与否应用 subschema 时,可以使用 dependentSchemas 关键字。此关键字允许您定义仅在存在或不存在特定属性时应用的 subschema。
Task
更新以确保如果存在 creditCardNumber 属性,那么使用 dependentSchemas 关键字也必须存在地址属性。
04-if-then-keyword
如果 isStudent 为真,则年龄字段必须存在。
05-if-then-else
如果 isStudent 为真,则必须显示年龄字段,否则必须显示年级字段。
06-Combining-Subschemas
01-Reusing-and-Referencing-with-defs-and-ref
组合子模式
在本模块中,您将学习如何组合多个子模式来创建更复杂的 JSON 模式。您将学习以下关键字:allOf、anyOf、oneOf、not、$defs、$ref 和递归模式。
在 JSON Schema 中,$defs关键字允许您定义可重用的子模式。然后可以使用$ref 关键字引用这些子模式。
要用
$defs
定义一个子模式,你可以使用以下语法:在上面的例子中,我们定义了一个名为 mySubschema 的子模式,它指定该值应该是一个最大长度为 10 个字符的字符串。
要使用
$ref
来引用这个子模式,你可以使用以下语法:在上面的例子中,我们使用
$ref
来引用 mySubschema 子模式。这允许我们在需要时重用mySubschema
的定义。通过促进代码重用,使用
$defs
和$ref
可以帮助您的 JSON 模式更加模块化和可维护。Task
在 schame 中定义名为 stringType 的子模式,它只是
“type”:“string”
,然后使用$ref
引用属性 firstName, middleName 和 lastName02-id-and-schema
$schema
在 JSON Schema 中,
$schema
是一个字符串,定义了写入该 schema 的 JSON Schema 标准的版本。在上面的示例中,架构是在 JSON Schema 草案 2020-12 中编写的。您可以在此处找到最新版本的 JSON Schema。
在本教程中,我们使用了 JSON Schema 草案 2020-12。
$id
$id
关键字是一个字符串,用于定义模式的 URI。在上面的示例中,模式的 URI 为
https://example.com/person
。模式 URI 可用于使用
$ref
关键字从其他模式引用该模式。Task
我们定义了一个简单的模式,如下所示。
在 schema 中使用
$ref
关键字在 name 属性中引用此模式。03-Valid-Against-allOf-the-Subschemas(AND)
当您希望确保一个实例对所有子模式都有效时,可以使用 allOf 关键字。
您可以将
allOf
视为子模式之间的 AND 操作。如果其中一个子模式失败,则认为该实例无效。我们将创建两个子模式
1. minStringLength
和2. 字母和数字
,然后使用 name 属性中的 allOf 将它们组合起来。上面的模式确保 name 属性对 minStringLength 和 alphannumeric 子模式都有效。换句话说,name 属性的最小长度必须为 5 个字符,并且必须只包含字母数字字符。
Task
定义一个内联子模式,检查 age 是否为整数类型
使用 age 属性中的 allOf 组合 ageLimit 和内联子模式。
04-Valid-Against-oneOf-the-Subschemas(XOR)
Example
让我们向 JSON 文档添加一个新的属性 dateOfBirth:
现在要在文档中应用这些条件:
Task
在侧面编辑器中为上面的 JSON 文档提供了一个模式。使用 oneOf 关键字,更新模式以确保年龄符合以下条件之一:
05-Valid-Against-anyOf-the-Subschemas(OR)
anyOf
关键字用于定义多个子模式。如果该实例对于任一子模式有效,则该文档被视为有效。Example
我们希望在文档中允许使用“age”和“dateOfBirth”属性。如果文档具有 Age 或 dateOfBirth 属性,则该文档有效。我们可以使用 anyOf 关键字来定义这个条件。
Task
要求:
06-inverting-validation-with-not
not
关键字用于反转验证。如果实例对于子模式无效,则该文档被视为有效。我们希望年龄大于或等于 18 岁。但不应该是 21 岁。我们可以使用 not 关键字来定义此条件。
Task
要求:
07-Recursive-Schemas
在 JSON 模式中,递归模式允许定义引用自身的模式。这在处理分层数据结构或建模递归关系时非常有用。
要定义递归模式,可以使用 $ref 关键字引用模式本身:
在上面的示例中,TreeNode 架构在 children 属性中引用自己,从而创建一个递归结构。
Task
使用递归模式定义 next schema:
07-Miscellaneous
01-Extending-Closed-Schemas-with-unevaluatedProperties
在前面的 Objects 模块中,我们学习了 addtionalProperties。但是,需要注意的是,addtionalProperties 只能识别在同一个子模式中声明的属性。
因此,addtionalProperties 可以限制您使用组合关键字(如 allOf)“扩展”模式。在下面的示例中,我们可以看到 addtionalProperties 如何导致扩展地址架构示例的尝试失败。
上述架构不允许您定义类型属性。因为 addtionalProperties 被设置为 false。原因是,addtionalProperties 只能识别在同一个子模式中声明的属性。
Unevaluated Properties
我们在 addtionalProperties 中看到的挑战可以使用 unevaluatedProperties 关键字来解决。此关键字允许您定义不由当前架构计算的属性。
Task
将 unevaluatedProperties 添加到架构中,以允许将数字
number
作为附加属性。08-Annotating-JSON-Schemas
01-Title-and-Description
title 和 description 关键字用于提供人类可读的模式标题和描述。
这些关键字不用于验证,但工具和软件可以使用它们来提供关于模式的更多信息。
02-deprecated-readOnly-and-writeOnly
deprecated
弃用关键字是一个布尔值,表示该关键字应用的实例值不应该被使用,将来可能会被删除。布尔关键字 readOnly 和 writeOnly 通常用于 API 上下文中。
readOnly
表示该值不能修改。它可以用来指示更改值的 PUT 请求将导致 400 Bad request 响应。writeOnly
表示可以设置一个值,但将保持隐藏。它可用于指示您可以使用 PUT 请求设置一个值,但在使用 GET 请求检索该记录时不会包含它。Task
deprecated
弃用关键字。03-comment-and-default
要在 JSON Schema 中添加注释,请使用$comment关键字。
$comment
关键字是一个字符串,它提供了关于模式的附加信息可以使用
default
关键字为属性设置默认值。default 关键字用于为属性提供默认值。The text was updated successfully, but these errors were encountered: