Reputation: 1207
I have a schema to validate an incoming JSON,
JSON Schema
{
'title': 'storage schema',
'description': 'storage schema',
'type': 'object',
'properties':{
'title': {
'title':'storage Name',
'type': 'string',
'minLength': 1,
'maxLength': 255
},
'storageType': {
'title': 'storage Type',
'enum' : ['DVD', 'HDD', 'Network', 'Internet']
},
'minCapacity': {
'title': 'Minimum Storage Capacity',
'type': 'number'
},
'maxCapacity': {
'title': 'Maximum Storage Capacity',
'type': 'number'
}
},
'additionalProperties':false,
'required':['title', 'storageType']
}
I would like to have minCapacity
and maxCapacity
properties to be present in the json if storageType
is DVD
or HDD
and not present in the json if the storageType
is Network
.
It can be done if i modify the schema to have storage as object and have min and max capacity as its properties, as in the schema below.
{
'title': 'storage schema',
'description': 'storage schema',
'type': 'object',
'properties':{
'title': {
'title':'storage Name',
'type': 'string',
'minLength': 1,
'maxLength': 255
},
'storage': {
'title': 'storage Details',
'type': 'object',
'oneOf' : [{'$ref': '#/storage/disk'},
{'$ref': '#/storage/network'}]
},
},
'additionalProperties':false,
'required':['title', 'storage'],
'storage':{
'disk':{
'properties':{
'type': {
'title': 'Storage Type',
'enum': ['HDD', 'DVD']
},
'minCapacity': {
'title': 'Minimum Storage Capacity',
'type': 'number'
},
'maxCapacity': {
'title': 'Maximum Storage Capacity',
'type': 'number'
}
},
'additionalProperties': false,
'required':['type', 'minCapacity', 'maxCapacity']
},
'network':{
'properties':{
'type': {
'title': 'Storage Type',
'enum': ['Network', 'Internet']
}
},
'additionalProperties': false,
'required':['type']
}
}
}
But I would like to achieve this without changing the structure of the schema.
Can it be done?
Valid Json 1
{
'title': 'additional mandatory properties',
'storageType': 'HDD',
'minCapacity': 0.1,
'maxCapacity': 1
}
Valid Json 2
{
'title': 'no additional mandatory properties',
'storageType': 'Network'
}
Invalid Json 1
{
'title': 'additional mandatory properties',
'storageType': 'Internet',
'minCapacity': 0.1,
'maxCapacity': 1
}
Invalid Json 2
{
'title': 'no additional mandatory properties',
'storageType': 'HDD'
}
UPDATE
when trying schema from jason's answer, it was not validating when only, one of the non required parameters is present in the json. The invalid JSON are given below.
Invalid Json 3
{
'title': 'additional mandatory properties',
'storageType': 'Internet',
'minCapacity': 0.1
}
Invalid Json 4
{
'title': 'additional mandatory properties',
'storageType': 'Internet',
'maxCapacity': 1
}
I solved this problem with a small modification to the schema in the not required part, which is as below.
{
"title": "storage schema",
"description": "storage schema",
"type": "object",
"properties": {
"title": {
"title": "storage Name",
"type": "string",
"minLength": 1,
"maxLength": 255
},
"storageType": {
"title": "storage Type"
},
"minCapacity": {
"title": "Minimum Storage Capacity",
"type": "number"
},
"maxCapacity": {
"title": "Maximum Storage Capacity",
"type": "number"
}
},
"required": ["title", "storageType"],
"anyOf": [
{
"properties": {
"storageType": {
"enum": ["DVD", "HDD"]
}
},
"required": ["minCapacity", "maxCapacity"]
},
{
"properties": {
"storageType": {
"enum": ["Network", "Internet"]
}
},
"allOf":[
{"not": {"required": ["maxCapacity"]}},
{"not": {"required": ["minCapacity"]}}
]
}
]
}
Upvotes: 1
Views: 2904
Reputation: 24489
Here is the solution.
{
"title": "storage schema",
"description": "storage schema",
"type": "object",
"properties": {
"title": {
"title": "storage Name",
"type": "string",
"minLength": 1,
"maxLength": 255
},
"storageType": {
"title": "storage Type"
},
"minCapacity": {
"title": "Minimum Storage Capacity",
"type": "number"
},
"maxCapacity": {
"title": "Maximum Storage Capacity",
"type": "number"
}
},
"additionalProperties": false,
"required": ["title", "storageType"],
"anyOf": [
{
"properties": {
"storageType": {
"enum": ["DVD", "HDD"]
}
},
"required": ["minCapacity", "maxCapacity"]
},
{
"properties": {
"storageType": {
"enum": ["Network", "Internet"]
}
},
"not": { "required": ["maxCapacity", "minCapacity"] }
}
]
}
P.S.
Use of "additionalProperties": false
is discouraged. Having to things like #/anyOf/1/not
is an example of how this feature can be more trouble than it's worth. Best practice is to simply ignore properties that don't belong.
Upvotes: 1