Reputation: 340
I am trying to add some validation to my json schema . I am validating json schema against json using this website https://www.jsonschemavalidator.net/. I am not able to put validation on eventPayload/totalAmount based on value present in eventName. It is not failing when it should fail. Should I give the whole path of eventName attribute as it is not present in eventPayload ? If yes, how to do that.
"totalAmount": {
"type": [
"integer",
"number"
],
"minLength": 1,
"multipleOf": 0.01,
"if": {
"properties": {
"eventName": {
"enum": [
"Test10",
"Test12"
]
}
}
},
"then": {
"properties": {
"totalAmount": {
"exclusiveMinimum": 0
}
}
},
"else": {
"if": {
"properties": {
"eventName": {
"enum": [
"Test1",
"Test2",
"Test3"
]
}
}
},
"then": {
"properties": {
"totalAmount": {
"exclusiveMaximum": 0
}
}
}
}
}
Upvotes: 0
Views: 793
Reputation: 657
It is not possible to reference values up the tree (e.g. totalAmount
is below eventName
), you have to define from the top down. Using oneOf
(instead of if/then/else
) and schema composition, you could solve it as follows (minimal example):
Schema:
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"eventName": {
"type": "string",
"enum": ["Test10", "Test12", "Test1", "Test2", "Test3"]
},
"eventPayload": {
"type": "object",
"properties": {
"totalAmount": {
"type": "number"
}
}
}
},
"oneOf": [
{
"properties": {
"eventName": {
"enum": ["Test10", "Test12"]
},
"eventPayload": {
"properties": {
"totalAmount": {
"exclusiveMinimum": 0
}
}
}
}
},
{
"properties": {
"eventName": {
"enum": ["Test1", "Test2", "Test3"]
},
"eventPayload": {
"properties": {
"totalAmount": {
"exclusiveMaximum": 0
}
}
}
}
}
]
}
Here, we first define the general structure in the properties
object (no validation yet, just the type of expected objects). Then, in the oneOf
array we add the alternatives: If eventName
is either "Test10" or "Test12" apply the exclusiveMinimum
, if it is one of the others, apply exclusiveMaximum
.
Any incoming json has to fulfill both the schema defined in properties
and one of the schemas in oneOf
. This way of layering schemas is how json schema implements composition. Using this schema and https://www.jsonschemavalidator.net/ we can verify that it
accepts
{
"eventName": "Test12",
"eventPayload": {
"totalAmount": 5
}
}
and
{
"eventName": "Test2",
"eventPayload": {
"totalAmount": -5
}
}
but rejects
{
"eventName": "Test12",
"eventPayload": {
"totalAmount": -5
}
}
and
{
"eventName": "Test2",
"eventPayload": {
"totalAmount": 5
}
}
Upvotes: 1
Reputation: 53966
The properties
keyword in your if
clause will evaluate to true if property eventName is not present. To ensure that it is, add "required": ["eventName"]
to the condition.
Upvotes: 0