Reputation: 2735
I know there is a similar question here, but it didn't really address my issue. In short, I want one my fields to be dependent on the other field's value. But for some values, I don't want any field to be required. Here is an example:
Schema
{
"definitions": {},
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"colour": {
"type": "string",
"enum": ["red", "black", "blue"]
},
"blackQuote": {
"type": "string",
"maxLength": 11
},
"redQuote": {
"type": "string",
"maxLength": 11
}
},
"oneOf": [
{
"properties": {
"colour": {"enum": ["red"]}
},
"required": ["redQuote"]
},
{
"properties": {
"colour": {"enum": ["black"]}
},
"required": ["blackQuote"]
}
],
"required": [
"colour"
]
}
This works like this:
Upvotes: 16
Views: 20543
Reputation: 24489
You can do this with a boolean logic concept called implication (!A or B). It can be used like an "if-then" statement. For example, either "color" is not "red" or "redQuote" is required. Any time I need to use this, I break it down with definitions
so it reads as nice as possible.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"colour": { "enum": ["red", "black", "blue"] },
"blackQuote": { "type": "string", "maxLength": 11 },
"redQuote": { "type": "string", "maxLength": 11 }
},
"allOf": [
{ "$ref": "#/definitions/red-requires-redQuote" },
{ "$ref": "#/definitions/black-requires-blackQuote" }
],
"required": ["colour"],
"definitions": {
"red-requires-redQuote": {
"anyOf": [
{ "not": { "$ref": "#/definitions/is-red" } },
{ "required": ["redQuote"] }
]
},
"black-requires-blackQuote": {
"anyOf": [
{ "not": { "$ref": "#/definitions/is-black" } },
{ "required": ["blackQuote"] }
]
},
"is-red": {
"properties": {
"colour": { "enum": ["red"] }
},
"required": ["colour"]
},
"is-black": {
"properties": {
"colour": { "enum": ["black"] }
},
"required": ["colour"]
}
}
}
Upvotes: 14
Reputation: 693
Simplest answer in draft-04 (as noted by Ganesh in a comment):
{
"definitions": {},
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"colour": {
"type": "string",
"enum": ["red", "black", "blue"]
},
"blackQuote": {
"type": "string",
"maxLength": 11
},
"redQuote": {
"type": "string",
"maxLength": 11
}
},
"oneOf": [
{
"properties": {
"colour": {"enum": ["red"]}
},
"required": ["redQuote"]
},
{
"properties": {
"colour": {"enum": ["black"]}
},
"required": ["blackQuote"]
},
{
"properties": {
"colour": {"enum": ["blue"]}
}
}
],
"required": [
"colour"
]
}
Upvotes: 6
Reputation: 6003
If you move the specifics of what you want into the OneOf's then you can keep it all pretty simple, especially if you end up with a load of other values for color.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"colour": {
"type": "string",
"enum": [
"red"
]
},
"redQuote": {
"type": "string",
"maxLength": 11
}
},
"required": [
"redQuote"
]
},
{
"type": "object",
"properties": {
"colour": {
"type": "string",
"enum": [
"black"
]
},
"blackQuote": {
"type": "string",
"maxLength": 11
}
},
"required": [
"blackQuote"
]
},
{
"type": "object",
"properties": {
"colour": {
"type": "string",
"enum": [
"blue"
]
}
}
}
],
"definitions": {}
}
Upvotes: 5