Reputation: 9790
I have a json-schema (draft-07) of type array to store multiple types of data like
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"data"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"enum": [
"banner_images",
"description_box",
"button"
]
},
"data": {
"type": "object"
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "banner_images"
}
}
},
"then": {
"properties": {
"data": {
"$ref": "components/banner_images.json"
}
}
}
},
{
"if": {
"properties": {
"type": {
"const": "description_box"
}
}
},
"then": {
"properties": {
"data": {
"$ref": "components/description_box.json"
}
}
}
},
{
"if": {
"properties": {
"type": {
"const": "button"
}
}
},
"then": {
"properties": {
"data": {
"$ref": "components/button.json"
}
}
}
}
]
}
}
Which validates the following data
[
{
"type": "banner_images",
"data": {
"images": [
{
"url": "https://example.com/image.jpg"
}
]
}
},
{
"type": "description_box",
"data": {
"text": "Description box text"
}
},
{
"type": "button",
"data": {
"label": "Click here",
"color": {
"label": "#ff000ff",
"button": "#00ff00",
"border": "#00ff00"
},
"link": "https://example.com"
}
}
]
As of now, the user can provide any number of the components from banner_images
, description_box
, and button
.
I want to limit each component based on the component type
There is an option to set the length of the items in array type https://json-schema.org/understanding-json-schema/reference/array.html#id7
But how can I limit the length of the items based on the type?
Upvotes: 1
Views: 2311
Reputation: 53966
You can do that by combining "contains" and "maxContains" (note this requires an implementation that supports draft version 2019-09 or later.)
In pseudocode: the components array has items containing objects with a property "type". When "type" is "banner_images", a maximum of 1 such item may exist. When "type" is "description_box", a maximum of 5 such item may exist. When "type" is "button", a maximum of 10 such item may exist.
That is:
"items": {
"type": "object",
...
},
"allOf": [
{
"contains": {
"properties": {
"type": {
"const": "banner_images"
}
}
},
"minContains": 0,
"maxContains": 1
},
{
"contains": {
"properties": {
"type": {
"const": "description_box"
}
}
},
"minContains": 0,
"maxContains": 5
},
{
"contains": {
"properties": {
"type": {
"const": "button"
}
}
},
"minContains": 0,
"maxContains": 10
},
]
Upvotes: 2