JSON Shema Reference

参考文档: https://json-schema.org/understanding-json-schema/reference/index.html

Type-specific keywords

参考文档: https://json-schema.org/understanding-json-schema/reference/type.html

The type keyword is fundamental to JSON Schema. It specifies the data type for a schema.

At its core, JSON Schema defines the following basic types:

  • string
  • number
  • integer
  • object
  • array
  • boolean
  • null

These types have analogs in most programming languages, though they may go by different names.

The type keyword may either be a string or an array:

  • If it’s a string, it is the name of one of the basic types above.
  • If it is an array, it must be an array of strings, where each string is the name of one of the basic types, and each element is unique. In this case, the JSON snippet is valid if it matches any of the given types.

Here is a simple example of using the type keyword:

{ "type": "number" }

In the following example, we accept strings and numbers, but not structured data types:

{ "type": ["number", "string"] }

ok: 42, "Life, the universe, and everything"

error: ["Life", "the universe", "and everything"]

For each of these types, there are keywords that only apply to those types. For example, numeric types have a way of specifying a numeric range, that would not be applicable to other types. In this reference, these validation keywords are described along with each of their corresponding types in the following chapters.

string

The string type is used for strings of text. It may contain Unicode characters.

keywords

Length

The length of a string can be constrained using the minLength and maxLength keywords. For both keywords, the value must be a non-negative number.

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

Regular Expressions

The <span class="pre">pattern</span> keyword is used to restrict a string to a particular regular expression. The regular expression syntax is the one defined in JavaScript (ECMA 262 specifically) with Unicode support. See Regular Expressions for more information.

Note:

When defining the regular expressions, it’s important to note that the string is considered valid if the expression matches anywhere within the string. For example, the regular expression "p" will match any string with a p in it, such as "apple" not just a string that is simply "p". Therefore, it is usually less confusing, as a matter of course, to surround the regular expression in ^...$, for example, "^p$", unless there is a good reason not to do so.

The following example matches a simple North American telephone number with an optional area code:

{
   "type": "string",
   "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
}

Format

The format keyword allows for basic semantic identification of certain kinds of string values that are commonly used. For example, because JSON doesn’t have a “DateTime” type, dates need to be encoded as strings. format allows the schema author to indicate that the string value should be interpreted as a date. By default, format is just an annotation and does not effect validation.

Optionally, validator implementations can provide a configuration option to enable format to function as an assertion rather than just an annotation. That means that validation will fail if, for example, a value with a date format isn’t in a form that can be parsed as a date. This can allow values to be constrained beyond what the other tools in JSON Schema, including Regular Expressions can do.

Note:

Implementations may provide validation for only a subset of the built-in formats or do partial validation for a given format. For example, some implementations may consider a string an email if it contains a @, while others might do additional checks for other aspects of a well formed email address.

There is a bias toward networking-related formats in the JSON Schema specification, most likely due to its heritage in web technologies. However, custom formats may also be used, as long as the parties exchanging the JSON documents also exchange information about the custom format types. A JSON Schema validator will ignore any format type that it does not understand.

Built-in formats

The following is the list of formats specified in the JSON Schema specification.

Dates and times

Dates and times are represented in RFC 3339, section 5.6. This is a subset of the date format also commonly known as ISO8601 format.

  • "date-time": Date and time together, for example, 2018-11-13T20:20:39+00:00.
  • "time": New in draft 7 Time, for example, 20:20:39+00:00
  • "date": New in draft 7 Date, for example, 2018-11-13.
  • "duration": New in draft 2019-09 A duration as defined by the ISO 8601 ABNF for “duration”. For example, P3D expresses a duration of 3 days.

Email addresses

Hostnames

IP Addresses

Resource identifiers

  • "uuid": New in draft 2019-09 A Universally Unique Identifier as defined by RFC 4122. Example: 3e4666bf-d5e5-4aa7-b8ce-cefe41c7568a
  • "uri": A universal resource identifier (URI), according to RFC3986.
  • "uri-reference": New in draft 6 A URI Reference (either a URI or a relative-reference), according to RFC3986, section 4.1.
  • "iri": New in draft 7 The internationalized equivalent of a “uri”, according to RFC3987.
  • "iri-reference": New in draft 7 The internationalized equivalent of a “uri-reference”, according to RFC3987

If the values in the schema have the ability to be relative to a particular source path (such as a link from a webpage), it is generally better practice to use "uri-reference" (or "iri-reference") rather than "uri" (or "iri"). "uri" should only be used when the path must be absolute.

Draft 4:

Draft 4 only includes "uri", not "uri-reference". Therefore, there is some ambiguity around whether "uri" should accept relative paths.

URI template

  • "uri-template": New in draft 6 A URI Template (of any level) according to RFC6570. If you don’t already know what a URI Template is, you probably don’t need this value.

JSON Pointer

  • "json-pointer": New in draft 6 A JSON Pointer, according to RFC6901. There is more discussion on the use of JSON Pointer within JSON Schema in Structuring a complex schema. Note that this should be used only when the entire string contains only JSON Pointer content, e.g. /foo/bar. JSON Pointer URI fragments, e.g. #/foo/bar/ should use "uri-reference".
  • "relative-json-pointer": New in draft 7 A relative JSON pointer.

Regular Expressions

  • "regex": New in draft 7 A regular expression, which should be valid according to the ECMA 262 dialect.

Be careful, in practice, JSON schema validators are only required to accept the safe subset of Regular Expressions described elsewhere in this document.

Regular Expressions

参考文档: https://json-schema.org/understanding-json-schema/reference/regular_expressions.html

The pattern and Pattern Properties keywords use regular expressions to express constraints. The regular expression syntax used is from JavaScript (ECMA 262, specifically). However, that complete syntax is not widely supported, therefore it is recommended that you stick to the subset of that syntax described below.

  • A single unicode character (other than the special characters below) matches itself.
  • .: Matches any character except line break characters. (Be aware that what constitutes a line break character is somewhat dependent on your platform and language environment, but in practice this rarely matters).
  • ^: Matches only at the beginning of the string.
  • $: Matches only at the end of the string.
  • (...): Group a series of regular expressions into a single regular expression.
  • |: Matches either the regular expression preceding or following the | symbol.
  • [abc]: Matches any of the characters inside the square brackets.
  • [a-z]: Matches the range of characters.
  • [^abc]: Matches any character not listed.
  • [^a-z]: Matches any character outside of the range.
  • +: Matches one or more repetitions of the preceding regular expression.
  • *: Matches zero or more repetitions of the preceding regular expression.
  • ?: Matches zero or one repetitions of the preceding regular expression.
  • +?, *?, ??: The *, +, and ? qualifiers are all greedy; they match as much text as possible. Sometimes this behavior isn’t desired and you want to match as few characters as possible.
  • (?!x>, (?=x): Negative and positive lookahead.
  • {x}: Match exactly x occurrences of the preceding regular expression.
  • {x,y}: Match at least x and at most y occurrences of the preceding regular expression.
  • {x,}: Match x occurrences or more of the preceding regular expression.
  • {x}?, {x,y}?, {x,}?: Lazy versions of the above expressions.

Example

The following example matches a simple North American telephone number with an optional area code:

{
   "type": "string",
   "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
}

Numeric types

参考文档: https://json-schema.org/understanding-json-schema/reference/numeric.html

There are two numeric types in JSON Schema: integer and number. They share the same validation keywords.

Note:

JSON has no standard way to represent complex numbers, so there is no way to test for them in JSON Schema.

integer

The integer type is used for integral numbers. JSON does not have distinct types for integers and floating-point values. Therefore, the presence or absence of a decimal point is not enough to distinguish between integers and non-integers. For example, 1 and 1.0 are two ways to represent the same value in JSON. JSON Schema considers that value an integer no matter which representation was used.

{ "type": "integer" }

Numbers with a zero fractional part are considered integers: 1.0

number

The number type is used for any numeric type, either integers or floating point numbers.

{ "type": "number" }

keywords

Multiples

Numbers can be restricted to a multiple of a given number, using the multipleOf keyword. It may be set to any positive number.

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

Range

Ranges of numbers are specified using a combination of the minimum and maximum keywords, (or exclusiveMinimum and exclusiveMaximum for expressing exclusive range).

If x is the value being validated, the following must hold true:

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

While you can specify both of minimum and exclusiveMinimum or both of maximum and exclusiveMaximum, it doesn’t really make sense to do so.

{
  "type": "number",
  "minimum": 0,
  "exclusiveMaximum": 100
}

Draft 4:

In JSON Schema Draft 4, exclusiveMinimum and exclusiveMaximum work differently. There they are boolean values, that indicate whether minimum and maximum are exclusive of the value. For example:

if exclusiveMinimum is false, x ≥ minimum. if exclusiveMinimum is true, x > minimum. This was changed to have better keyword independence.

Here is an example using the older Draft 4 convention:

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "exclusiveMaximum": true
}

boolean

参考文档: https://json-schema.org/understanding-json-schema/reference/boolean.html

The boolean type matches only two special values: true and false. Note that values that evaluate to true or false, such as 1 and 0, are not accepted by the schema.

{ "type": "boolean" }

null

When a schema specifies a type of null, it has only one acceptable value: null.

{ "type": "null" }

ok: null

error: false, 0, "",

array

参考文档: https://json-schema.org/understanding-json-schema/reference/array.html

Arrays are used for ordered elements. In JSON, each element in an array may be of a different type.

{ "type": "array" }

ok:

[1, 2, 3, 4, 5]

[3, "different", { "types" : "of values" }]

error:

{"Not": "an array"}

There are two ways in which arrays are generally used in JSON:

  • List validation: a sequence of arbitrary length where each item matches the same schema.
  • Tuple validation: a sequence of fixed length where each item may have a different schema. In this usage, the index (or location) of each item is meaningful as to how the value is interpreted. (This usage is often given a whole separate type in some programming languages, such as Python’s tuple).

keywords

Items

List validation is useful for arrays of arbitrary length where each item matches the same schema. For this kind of array, set the items keyword to a single schema that will be used to validate all of the items in the array.

In the following example, we define that each item in an array is a number:

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

ok:

[1, 2, 3, 4, 5]

The empty array is always valid:

[]

error:

A single “non-number” causes the whole array to be invalid:

[1, 2, "3", 4, 5]

Tuple validation

Tuple validation is useful when the array is a collection of items where each has a different schema and the ordinal index of each item is meaningful.

For example, you may represent a street address such as:

600 Pennsylvania Avenue NW

as a 4-tuple of the form:

[number, street_name, street_type, direction]

Each of these fields will have a different schema:

  • number: The address number. Must be a number.
  • street_name: The name of the street. Must be a string.
  • street_type: The type of street. Should be a string from a fixed set of values.
  • direction: The city quadrant of the address. Should be a string from a different set of values.

To do this, we use the prefixItems keyword. prefixItems is an array, where each item is a schema that corresponds to each index of the document’s array. That is, an array where the first element validates the first element of the input array, the second element validates the second element of the input array, etc.

Draft4 - 2019-09

In Draft 4 - 2019-09, tuple validation was handled by an alternate form of the items keyword. When items was an array of schemas instead of a single schema, it behaved the way prefixItems behaves.

Here’s the example schema:

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

ok:

[1600, "Pennsylvania", "Avenue", "NW"]

It’s okay to not provide all of the items:

[10, "Downing", "Street"]

And, by default, it’s also okay to add additional items to end:

[1600, "Pennsylvania", "Avenue", "NW", "Washington"]

error:

“Drive” is not one of the acceptable street types:

[24, "Sussex", "Drive"]

This address is missing a street number

["Palais de l'Élysée"]

Additional Items

The items keyword can be used to control whether it’s valid to have additional items in a tuple beyond what is defined in prefixItems. The value of the items keyword is a schema that all additional items must pass in order for the keyword to validate.

Draft4 - 2019-09

Before to Draft 2020-12, you would use the additionalItems keyword to constrain additional items on a tuple. It works the same as items, only the name has changed.

Draft6 - 2019-09

In Draft 6 - 2019-09, the additionalItems keyword is ignored if there is not a “tuple validation” items keyword present in the same schema.

Here, we’ll reuse the example schema above, but set items to false, which has the effect of disallowing extra items in the tuple.

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

ok:

[1600, "Pennsylvania", "Avenue", "NW"]

It’s ok to not provide all of the items:

[1600, "Pennsylvania", "Avenue"]

error:

But, since items is false, we can’t provide extra items:

[1600, "Pennsylvania", "Avenue", "NW", "Washington"]

You can express more complex constraints by using a non-boolean schema to constrain what value additional items can have. In that case, we could say that additional items are allowed, as long as they are all strings:

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

Extra string items are ok …

[1600, "Pennsylvania", "Avenue", "NW", "Washington"]

… but not anything else

[1600, "Pennsylvania", "Avenue", "NW", 20500]

Unevaluated Items

New in draft 2019-09

Documentation Coming Soon

Contains

New in draft 6

While the items schema must be valid for every item in the array, the contains schema only needs to validate against one or more items in the array.

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

ok:

A single “number” is enough to make this pass:

["life", "universe", "everything", 42]

All numbers is, of course, also okay:

[1, 2, 3, 4, 5]

But if we have no number, it fails:

["life", "universe", "everything", "forty-two"]

minContains / maxContains

New in draft 2019-09

minContains and maxContains can be used with contains to further specify how many times a schema matches a contains constraint. These keywords can be any non-negative number including zero.

{
  "type": "array",
  "contains": {
    "type": "number"
  },
  "minContains": 2,
  "maxContains": 3
}

error:

Fails minContains

["apple", "orange", 2]

Fails maxContains

["apple", "orange", 2, 4, 8, 16]

ok:

["apple", "orange", 2, 4]

["apple", "orange", 2, 4, 8]

Length

The length of the array can be specified using the minItems and maxItems keywords. The value of each keyword must be a non-negative number. These keywords work whether doing list validation or Tuple validation.

{
  "type": "array",
  "minItems": 2,
  "maxItems": 3
}

ok:

[1, 2]

[1, 2, 3]

error:

[]

[1]

[1,2,3,4]

Uniqueness

A schema can ensure that each of the items in an array is unique. Simply set the uniqueItemskeyword to true.

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

ok:

[1, 2, 3, 4, 5]

The empty array always passes: []

error:

[1, 2, 3, 3, 4]