Reputation: 158
I have a schema like this:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"foo": {
"enum": [
"foo1",
"foo2"
]
},
"bar": {
"type": "number"
},
}
I want bar to be required if foo is present and if it has value "foo1", otherwise it should be forbidden. I was trying something like:
"if": {
"properties": {
"foo": {
"const": "foo1"
}
}
},
"then": {
"required": [
"bar"
]
},
"else": {
"not": {
"required": [
"bar"
]
}
}
However, what happens is if foo is not present, then bar is required and I don't want that. It's as if absence of the field is interpreted as true by the if statement. Is there a way to make one field required only if another optional field is present and has specific value? Something like:
"if": {
allOf: [
{
"properties": {
"foo": {
"const": "foo1"
}
}
},
{
"contains": "foo"
}
]
}
"then": {
"required": [
"bar"
]
},
"else": {
"not": {
"required": [
"bar"
]
}
}
By the way I've found many similar questions here, but none where foo is not required.
Upvotes: 0
Views: 1388
Reputation: 158
After few more hours I came up with a solution, which I'm going to post here, because it works for earlier versions of json schema, where if/then/else are not available, so someone might need it if they are unable to upgrade, but I accepted Relequestual's answer, because his solution is more elegant for those who have latest version at their disposal
"oneOf":
[
{
"not": {"required": ["foo", "bar"]}
},
{
"required": ["foo"],
"anyOf": [
{
"properties":{
"foo":{"enum": ["foo1"]}
},
"required": ["bar"]
},
{
"properties":{
"foo": {"not": {"enum": ["foo1"]}}
},
"not": {"required": ["bar"]}
}
]}
]
Upvotes: 0
Reputation: 12295
The values of the if/then/else
keywords are schemas themselves.
What happens if you take the schema value of your if
keyword on its own?
What you'll find is, it will validate an empty object successfully without error.
properties
only applies subschemas to instance locations where the keys match. If your object has no foo
property, you're not doing any validation on the object.
You need to add required
to your if statement for this to work how you expect.
"if": {
"properties": {
"foo": {
"const": "foo1"
}
},
"required": ["foo"]
}
See it in action here: https://jsonschema.dev/s/L0rlG
Upvotes: 2