Redfish Schema语法手册

具体类型定义

JSON Schema中用type关键字来描述数据的类型,定义了6种基本数据类型:

type关键字可以用字符串或者数组来描述。字符串从以上6种数据类型中取值;数组必须由以上6种数据类型的字符串组成,表明type可以是数组中表示的任意数据类型。

string

string为字符串类型。

{ "type": "string" }

"Hello" // OK
""      // OK
"10"    // OK
10      // WRONG!

另外,可以用一些关键字辅助type进行类型校验,关键字与type平级。

Length

minLengthmaxLength关键字描述字符串的最小和最大长度,对应值为非负整数

{
    "type": "string",
    "minLength": 2,
    "maxLength": 3
}

"Hello" // WRONG!
"Hi"    // OK

Regular Expressions

pattern关键字可以正则描述字符串内容,具体语法见regular expression syntax章节。

{
    "type": "string",
    "pattern": "^He"
}

"Hello"     // OK
"Hi"        // WRONG!
"say Hello" // WRONG!

Format

format关键字用于描述字符串的格式,默认为注释,不具有校验规则。

formatvalidator组合使用可以用于校验字符串的格式,使format可以作为断言而不仅是注释。

format有内置的类型定义:

  • Dates and times

"date-time"用于表示例如:2018-11-13T20:20:39+00:00
"time"用于表示例如:20:20:39+00:00
"date"用于表示例如:2018-11-13
"duration"用于表示一段时间,例如P3D可以表示3天的时间。

  • Email addresses

"email"
"idn-email"

  • Hostnames

"hostname"
"idn-hostname"

  • IP Addresses

"ipv4"
"ipv6"

  • Resource identifiers

"uuid"
"uri"
"uri-reference"
"iri"
"iri-reference"

  • URI template

"uri-template"

  • JSON Pointer

"json-pointer"
"relative-json-pointer"

  • Regular Expressions

"regex"

numeric types

integer

integer用于表示整型数字。JSON没有区分整型和浮点型的具体类型,所以有没有小数点不能作为JSON中判断是否是整型的依据。

{ "type": "integer" }

42   // OK
-1   // OK
1.0  // OK
3.14 // WRONG!
"42" // WRONG!

number

number用于表示任意数字,包括整型和浮点型。

{ "type": "number" }

42   // OK
-1   // OK
1.0  // OK
3.14 // OK
"42" // WRONG!

Multiples

multipleOf关键字用于限制数字为给定数字的倍数,给定数字必须是任意正数

{
    "type": "number",
    "multipleOf": 10
}

0  // OK
20 // OK
21 // WRONG!

{
    "type": "number",
    "multipleOf" : 0.01
}

4.02  // OK
4.021 // WRONG!

Range

minimummaximum关键字用于限制数字的范围,exclusiveMinimumexclusiveMaximum关键字用于排除边界的范围限制。

x ≥ minimum
x > exclusiveMinimum
x ≤ maximum
x < exclusiveMaximum

这些限制条件可以组合使用,且都会生效。

在JSON Draft 4中(我们没有使用),exclusiveMinimumexclusiveMaximum关键字的值为true或者false,表示是否排除最大/最小边界。

object

object是JSON中的映射类型,将"keys"映射到"values","keys"必须是字符串,每一对通常指一个“属性”。

Properties

properties关键字用于描述一系列属性。properties本身是object类型,对象中的每一个key都是属性名,每一个value都是用于描述该属性的schema. 任何在properties中与属性名不匹配的关键字都会被忽略。

{
    "type": "object",
    "properties": {
        "number": { "type": "number" },
        "street_name": { "type": "string" },
        "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
    }
}

{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }                    // OK
{ "number": "1600", "street_name": "Pennsylvania", "street_type": "Avenue" }                  // WRONG!
{ "number": 1600, "street_name": "Pennsylvania" }                                             // OK
{  }                                                                                          // OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" } // OK

Pattern Properties

patternProperties是用于描述属性名匹配为正则模式的关键字,如果关键字下描述的属性名能够匹配,则会有对应的schema校验。

Additional Properties

additionalProperties关键字用于描述不在properties下或不在patternProperties下的额外属性,value为用于描述额外属性的schema.

addtionalProperties的值直接设置为false表示不允许任何额外属性。

{
    "type": "object",
    "properties": {
        "number": { "type": "number" },
        "street_name": { "type": "string" },
        "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
    },
    "additionalProperties": false
}

{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }                    // OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" } // WRONG!

也可以用schema来描述额外属性的数据格式。

{
    "type": "object",
    "properties": {
        "number": { "type": "number" },
        "street_name": { "type": "string" },
        "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
    },
    "additionalProperties": { "type": "string" }
}

{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }                       // OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" }    // OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "office_number": 201 } // WRONG!

propertiespatternProperties也可以与addtionalProperties组合使用。

Unevaluated Properties

unevaluatedProperties的作用与additionalProperties基本一致,区别在于unevaluatedProperties可以识别子模式中声明的属性。也就是说,unevaluatedProperties捕获的是未被其它属性模式捕获的属性。

{
    "type": "object",
    "properties": {
        "street_address": { "type": "string" },
        "city": { "type": "string" },
        "state": { "type": "string" },
        "type": { "enum": ["residential", "business"] }
    },
    "required": ["street_address", "city", "state", "type"],

    "if": {
        "type": "object",
        "properties": {
            "type": { "const": "business" }
        },
        "required": ["type"]
    },
    "then": {
        "properties": {
            "department": { "type": "string" }
        }
    },

    "unevaluatedProperties": false
}

{
    "street_address": "1600 Pennsylvania Avenue NW",
    "city": "Washington",
    "state": "DC",
    "type": "business",
    "department": "HR"
}   // OK
{
    "street_address": "1600 Pennsylvania Avenue NW",
    "city": "Washington",
    "state": "DC",
    "type": "residential",
    "department": "HR"
}   // WRONG!

Required Properties

required关键字表示properties中必须出现的属性名列表,描述required的数据类型为由字符串组成的数组

Property names

propertyNames可以用于以正则校验属性名格式。由于对象keys不论如何必须是字符串类型,因此在声明propertyNames默认含有{ "type": "string" }规则。

Size

minPropertiesmaxProperties可以用于限制一个对象中的属性个数,给定的数字必须是正整数

array

对于数组有2种验证方式:

  • 列表验证:用于描述匹配相同schema的任意长度序列;
  • 元组验证:用于描述匹配不同schema的固定长度序列。

Items

items用于描述数组中所有元素都要满足的schema,数组可以是任意长度的。

Tuple validation

prefixItems用于验证固定长度和模式的数组。描述prefixItems的数据类型为数组,其中每一个元素都是一个对象,第一个对象描述数组中第一个元素的数据模式,第二个对象描述数组中第二个元素的数据模式,以此类推。

{
    "type": "array",
    "prefixItems": [
        { "type": "number" },
        { "type": "string" },
        { "enum": ["Street", "Avenue", "Boulevard"] },
        { "enum": ["NW", "NE", "SW", "SE"] }
    ]
}

[1600, "Pennsylvania", "Avenue", "NW"] // OK
[10, "Downing", "Street"]              // OK
[24, "Sussex", "Drive"]                // WRONG!
["Palais de l'Élysée"]                 // WRONG!

Additional Items

items可以用于描述未在prefixItems中描述的额外元素的数据模式。

Unevaluated Items

unevaluatedItems关键字作用与Items基本一致,区别在于items不能识别子模式中的数据模式,会直接忽略allOf,anyOf, 或者oneOf中的子模式;而unevaluatedItems会校验子模式。

{
    "allOf": [
        { "prefixItems": [
            { "type": "boolean" },
            { "type": "string" }
        ] }
    ],
    "items": { "const": 2 }
}

[true, "a", 2] // WRONG!

{
    "allOf": [
        { "prefixItems": [
            { "type": "boolean" },
            { "type": "string" }
        ] }
    ],
    "unevaluatedItems": { "const": 2 }
}

[true, "a", 2] // OK

Contains

contains用于校验数组中一个或多个元素的数据模式,只要数组中有一个元素满足contains中的模式,就可以通过校验。

{
    "type": "array",
    "contains": {
        "type": "number"
    }
}

["life", "universe", "everything", 42]          // OK
["life", "universe", "everything", "forty-two"] // WRONG!
[1, 2, 3, 4, 5]                                 // OK

minContains / maxContains

minContainsmaxContains用于描述数组中满足contains描述数据模式的个数限制。

Length

minItemsmaxItems关键字用于限制数组中元素的总个数。

Uniqueness

uniqueItems关键字用于描述数组中的元素是否是独一无二的。

{
    "type": "array",
    "uniqueItems": true
}

[1, 2, 3, 4, 5] // OK
[1, 2, 3, 3, 4] // WRONG!

boolean

boolean只接受2个特定值:truefalse,其余值例如1和0都不会被接受。

null

当数据类型type被定义为null时,代表只接受null值,空值不包含在内。

Enumerated values

enum关键字用于限制取值在给出的固定取值集合中,enum的value必须为至少有1个元素的数组,且每个元素都必须是独一无二的

{
    "enum": ["red", "amber", "green", null, 42]
}

"red" // OK
null  // OK
42    // OK
0     // WRONG!

Constant values

const关键字用于限制取值为给定的值。

{
    "properties": {
        "country": {
            "const": "United States of America"
        }
    }
}

{ "country": "United States of America" } // OK
{ "country": "Canada" }                   // WRONG!

regular expression syntax

Schema Composition

JSON Schema囊括了一些可以把schema组合到一起共同描述复杂schema结构的关键字,结合这些关键字可以让一个值被多条规则同时校验。这些关键字对应于众所周知的boolean代数概念如AND, OR, XOR和NOT.

这些用于组合schema的关键字是:

  • allOf: (AND)必须满足所有涉及子模式
  • anyOf: (OR)必须满足任意一个涉及子模式
  • oneOf: (XOR)必须满足正好一个涉及子模式
    以上所有关键字必须被组合到一个数组,每一个元素是一个schema. 递归模式会成倍增加处理时间。

另外,

  • not: (NOT)必须不能满足给定的schema

在组合这些关键字时,非常容易出现互相矛盾的描述,导致无法通过校验,注意不要产生自相矛盾的逻辑。

allOf

验证allOf时,会验证所有给定的子模式。

{
    "allOf": [
        { "type": "string" },
        { "maxLength": 5 }
    ]
}

"short"    // OK
"too long" // WRONG!

注意allOf中的子模式不能互相有继承、依赖关系,实例必须独立地满足allOf中的所有schema.

anyOf

验证anyOf时,会验证通过一个或多个给定的子模式。

{
    "anyOf": [
        { "type": "string", "maxLength": 5 },
        { "type": "number", "minimum": 0 }
    ]
}

"short"    // OK
"too long" // WRONG!
12         // OK
-5         // WRONG!

oneOf

验证oneOf时,只能验证通过有且仅有一个给定的子模式。

{
  "oneOf": [
    { "type": "number", "multipleOf": 5 },
    { "type": "number", "multipleOf": 3 }
  ]
}

10 // OK
9  // OK
2  // WRONG!
15 // WRONG!

not

验证not时,会验证不通过所有给定的子模式。

{ "not": { "type": "string" } }

42                 // OK
{ "key": "value" } // OK
"I am a string"    // WRONG!

dependentRequired

dependentRequired关键字描述key属性存在时,value中的属性也必须给出;key属性不存在时,value中的属性则不作要求这样的数据模式。dependentRequired以object描述,每一个key属性的value以array描述。

以下面的schema为例,描述了credit_card存在时,必须有billing_address作为寄送信用卡的地址;credit_card不存在时,则对billing_address不作要求:

{
    "type": "object",

    "properties": {
        "name": { "type": "string" },
        "credit_card": { "type": "number" },
        "billing_address": { "type": "string" }
    },

    "required": ["name"],

    "dependentRequired": {
        "credit_card": ["billing_address"]
    }
}

{
    "name": "John Doe",
    "credit_card": 5555555555555555,
    "billing_address": "555 Debtor's Lane"
}   // OK
{
  "name": "John Doe",
  "credit_card": 5555555555555555
}   // WRONG
{
  "name": "John Doe",
  "billing_address": "555 Debtor's Lane"
}   // OK

dependentSchemas

dependentSchemas关键字描述key属性存在时,需要满足的子模式。子模式schema与allOf校验规则相同。

Draft 2019-09之前,dependentRequireddependentSchemas都是同样的关键字dependencies. 如果对应值是一个数组,功能就类似dependentRequired,如果对应值是一个schema, 功能就类似dependentSchema.

If-Then-Else

if, thenelse关键字允许子模式根据另一个schema的校验结果生效。

if then else whole schema
T T n/a T
T F n/a F
F n/a T T
F n/a F F
n/a n/a n/a T

Annotations

JSON Schema包括了一些不会用于校验的关键字,这些关键字用于描述一部分schema. 这些类似“注释”的关键字都不是必需的,但鼓励用户在设计过程中使用,增强可读性。

注释类的关键字可以被用在任意模式或子模式中,且同一关键字在同一层只能使用一次。

  • titledescription必须是字符串title要尽可能的简短,而description则提供关于这部分schema描述内容的详细说明。
  • default表示一个默认值,这个值不会在验证过程中自动填充,而是作为建议给用户进行说明。default表示的值应当与值缺失时自动填充的值一致。
  • examples表示一个例子组成的数组用于给出符合schema的例子。这个字段不会用于校验,但是可以给后续阅读者反应这段schema的用途。
  • readOnlywriteOnly一般用于API上下文中,用于表示该值仅用于读/写。
  • $comment用于给schema文件添加评论。

$schema

$schema关键字用于声明该schema是用哪个版本的JSON Schema写的。$schema关键字的值也可以用来作为判断校验schema的版本的依据,一般作用于整篇文档,必须放在根目录。