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?
CodePudding user response:
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.