I have the following JSON file which I want to validate:
{"topic_name": "test_topic",
"partitions": 15,
"factor": 3,
"configuration":
[
{"name": "retention.ms", "value": 302400000},
{"name": "delete.retention", "value": "null"},
{"name": "cleanup", "value": "delete"}
]
}
I now validate using this Schema:
{
"type": "object",
"uniqueItems": true,
"properties": {
"factor": {
"type": "number"
},
"partitions": {
"type": "number",
"minimum": 3,
"maximum": 15
},
"configuration": {
"type": "array",
"uniqueItems": true,
"prefixItems": [
{
"type": "object",
"maxProperties": 2,
"properties": {
"name": {"type": "string"},
"value": {"type": "number"}
}
},
{
"type": "object",
"properties": {
"name": {"type": "string"},
"value": {"type": "string"}
}
},
{
"type": "object",
"properties": {
"name": {"type": "string"},
"value": {"type": "string"}
}
},
]
}
},
"required": [
"partitions_count",
"replication_factor",
"configs",
"topic_name"
]
}
The problem I face with my current schema is that the ordering is fixed. I want to validate each item in my configuration key to a different type. Retention should be integer, cleanup should be string. I do not know how to do this. I tried it with the "items" keyword, but although every "name" key should have a "string" value. The "value" key can have different classes requirements which is dependent on the name. Any ideas?
JSON Schema is not designed to validate conditionally based on instance data. But it is possible to some extent using if-then-else
(Tutorial) or oneOf/anyOf/allOf
often in combination with const
and pattern
(Tutorial) checking:
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
"properties": {
"configuration": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"if": {
"properties": {
"name": {
"pattern": "cleanup"
}
}
},
"then": {
"properties": {
"value": {
"type": "string"
}
}
},
"else": false
},
{
"type": "object",
"if": {
"properties": {
"name": {
"pattern": "delete.retention"
}
}
},
"then": {
"properties": {
"value": {
"type": "null"
}
}
},
"else": false
},
{
"type": "object",
"if": {
"properties": {
"name": {
"pattern": "retention.ms"
}
}
},
"then": {
"properties": {
"value": {
"type": "integer"
}
}
},
"else": false
}
]
}
}
}
}
Please note that you can use any regular expression with the pattern
keyword.