I have a json schema that works when I use 2 oneOf for 2 choices between required fields. But I don't know how to do the same with optional fields.
My schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"a": {
"type": "number"
},
"b": {
"type": "number"
},
"c": {
"type": "number"
},
"d": {
"type": "number"
},
"e": {
"type": "number"
}
},
"required": ["a"],
"oneOf": [
{"required": ["b"]},
{"required": ["c"]}
],
"oneOf": [
{"required": ["d"]},
{"required": ["e"]}
]
}
How can I transform to make d and e optional (while never having both at once)?
Here's a gist with my solution, shown in http://jsonschemalint.com. (Very handy tool!)
Properties d
and e
are already defined, and allowed (but not required) in any combination. To make these two properties mutually exclusive, we say that the instance must not
match a schema that has both properties:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
"c": {"type": "number"},
"d": {"type": "number"},
"e": {"type": "number"}
},
"required": ["a"],
"oneOf": [
{"required": ["b"]},
{"required": ["c"]}
],
"not" : {"required" : ["d","e"]}
}
This works nicely, but it starts getting messy if you have more than two properties in your mutually exclusive group. For example, if we wanted to add property f
and make it mutually exclusive with respect to d
and e
, we'd have to disallow three distinct combinations:
"not" : {
"anyOf"{
{"required" : ["d","e"]},
{"required" : ["d","f"]},
{"required" : ["e","f"]},
}
}
Here's an alternative that's more verbose, but scales up to larger sets of mutually exclusive properties:
"oneOf" : [
{"required" : ["d"]},
{"required" : ["e"]},
{"required" : ["f"]},
{
"not" : {
"anyOf" : [
{"required" : ["d"]},
{"required" : ["e"]},
{"required" : ["f"]}
]
}
}
]
Each property added to the group requires exactly two lines.
Since our schema now has two oneOf
constraints, we need to combine them using allOf
:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
"c": {"type": "number"},
"d": {"type": "number"},
"e": {"type": "number"},
"f": {"type": "number"}
},
"required": ["a"],
"allOf": [
{
"oneOf": [
{"required": ["b"]},
{"required": ["c"]}
]
},
{
"oneOf" : [
{"required" : ["d"]},
{"required" : ["e"]},
{"required" : ["f"]},
{
"not" : {
"anyOf" : [
{"required" : ["d"]},
{"required" : ["e"]},
{"required" : ["f"]}
]
}
}
]
}
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With