Arrays are used for ordered elements. In JSON, each element in an array may be of a different type.
Language-specific info:
Python
Ruby
Objective-C
Swift
In Python, "array" is analogous to the list
or tuple
type, depending on usage. However, the json
module in the Python standard library will always use Python lists to represent JSON arrays.
compliant to schema
[3, "different", { "types": "of values" }]
compliant to schema
not compliant to schema
There are two ways in which arrays are generally used in JSON:
tuple
).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:
schema{ "type": "array", "items": { "type": "number" }}
compliant to schema
A single "non-number" causes the whole array to be invalid:
not compliant to schema
The empty array is always valid:
compliant to schema
Tuple validationTuple 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 1600 Pennsylvania Avenue NW
as a 4-tuple of the form:
[number, street_name, street_type, direction]
[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.
Draft-specific info
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:
schema{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ]}
[1600, "Pennsylvania", "Avenue", "NW"]
compliant to schema
"Drive" is not one of the acceptable street types:
not compliant to schema
This address is missing a street number:
not compliant to schema
It's okay to not provide all of the items:
[10, "Downing", "Street"]
compliant to schema
And, by default, it's also okay to add additional items to end:
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
compliant to schema
Additional ItemsThe 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.
Draft 4 - 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.
Draft 6 - 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}
[1600, "Pennsylvania", "Avenue", "NW"]
compliant to schema
It's ok to not provide all of the items:
[1600, "Pennsylvania", "Avenue"]
compliant to schema
But, since items
is false
, we can't provide extra items:
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
not compliant to schema
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:
schema{ "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"]
compliant to schema
... but not anything else
[1600, "Pennsylvania", "Avenue", "NW", 20500]
not compliant to schema
Unevaluated ItemsNew in draft 2019-09
The unevaluatedItems
keyword is useful mainly when you want to add or disallow extra items to an array.
unevaluatedItems
applies to any values not evaluated by an items
, prefixItems
, or contains
keyword. Just as unevaluatedProperties
affects only properties in an object, unevaluatedItems
affects only items in an array.
Watch out! The word "unevaluated" does not mean "not evaluated by items
, prefixItems
, or contains
." "Unevaluated" means "not successfully evaluated", or "does not evaluate to true".
Like with items
, if you set unevaluatedItems
to false
, you can disallow extra items in the array.
{ "prefixItems": [ { "type": "string" }, { "type": "number" } ], "unevaluatedItems": false}
Here, all the values are evaluated. The schema passes validation.
compliant to schema
But here, the schema fails validation because "unevaluatedItems": false
specifies that no extra values should exist.
not compliant to schema
Note that items
doesn't "see inside" any instances of allOf
, anyOf
, or oneOf
in the same subschema. So in this next example, items
ignores allOf
and thus fails to validate.
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "items": { "const": 2 }}
not compliant to schema
But if you replace items
with unevaluatedItems
, then the same array validates.
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "unevaluatedItems": { "const": 2 }}
compliant to schema
You can also make a "half-closed" schema: something useful when you want to keep the first two arguments, but also add more in certain situations. ("Closed" to two arguments in some places, "open" to more arguments when you need it to be.)
schema{ "$id": "https://example.com/my-tuple", "type": "array", "prefixItems": [ { "type": "boolean" }, { "type": "string" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
Here the schema is "closed" to two array items. You can then later use $ref
and add another item like this:
{ "$id": "https://example.com/my-extended-tuple", "$ref": "https://example.com/my-tuple", "prefixItems": [ { "type": "boolean" }, { "type": "string" }, { "type": "number" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
Thus, you would reference my-tuple#closed
when you need only two items and reference my-tuple#extended
when you need three items.
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" }}
A single "number" is enough to make this pass:
["life", "universe", "everything", 42]
compliant to schema
But if we have no number, it fails:
["life", "universe", "everything", "forty-two"]
not compliant to schema
All numbers is, of course, also okay:
compliant to schema
minContains / maxContainsNew 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}
Fails minContains
not compliant to schema
["apple", "orange", 2, 4]
compliant to schema
["apple", "orange", 2, 4, 8]
compliant to schema
Fails maxContains
["apple", "orange", 2, 4, 8, 16]
not compliant to schema
LengthThe 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}
not compliant to schema
not compliant to schema
compliant to schema
compliant to schema
not compliant to schema
UniquenessA schema can ensure that each of the items in an array is unique. Simply set the uniqueItems
keyword to true
.
{ "type": "array", "uniqueItems": true}
compliant to schema
not compliant to schema
The empty array always passes:
compliant to schema
Need Help? Did you find these docs helpful? Help us make our docs great!At JSON Schema, we value docs contributions as much as every other type of contribution!
Still Need Help?Learning JSON Schema is often confusing, but don't worry, we are here to help!.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4