JSON Schema dependency based on minimum value - json

I am trying to add a dependency to a property based on the property value before it. Within my JSON, there is an instances property. If that property is > 2 only then show the StartIndex property. I have tried adding another if-then-else to my pre-existing one (wrapped in an allOf) but that was failing so I decided to take the dependency route.
Here's the JSON Schema with my attempt at adding the dependency withing the StartIndex property:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": " ",
"required": [
"NetworkProfile",
"GroupEmailAddress",
"FILESTORAGE",
"Memory",
"Instances",
"StartIndex"
],
"properties": {
"Name": {
"$id": "#/properties/Name",
"type": "string",
"title": "Name",
"default": "",
"description": "The first five characters are generated per specs. Specify the next eight characters here and we suggest: Data Center (2), Layer (2-3), Sequential Number (2).",
"examples": [
""
],
"minLength": 0,
"maxLength": 8,
"pattern": "^[a-zA-Z0-9]*$",
"validationMessages": {
"pattern": "Must contain only alphanumeric characters.",
"required": "Must contain only alphanumeric characters."
}
},
"Instances": {
"$id": "#/properties/Instances",
"default": 2,
"examples": [
"2"
],
"pattern": "^(.*)$",
"title": "Number of VM Node",
"description": "Number of VM instance in this request",
"minimum": 1,
"maximum": 5,
"type": "number"
},
"StartIndex": {
"dependencies": {
"Instances": {
"minimum": 2
}
},
"$id": "#/properties/StartIndex",
"default": 1,
"examples": [
"1"
],
"pattern": "^(.*)$",
"title": "Start Index for these VMs",
"description": "The starting sequence number for this set of servers",
"type": "number",
"minimum": 1
},
"Memory": {
"$id": "#/properties/Memory",
"type": "number",
"enum": [
4,
8,
16
],
"title": "RAM (GB)",
"default": 4,
"examples": [
""
],
"pattern": "^(.*)$"
},
"GroupEmailAddress": {
"$id": "#/properties/GroupEmailAddress",
"type": "string",
"title": "Group Email Address",
"default": "",
"description": "This should be an email address for your application group. Security will use this email address to contact when TLS cert needs to be renewed.",
"examples": [
""
]
},
"User": {
"$id": "#/properties/User",
"type": "string",
"title": "Admin Group",
"default": "",
"examples": [
""
],
"description": "The user account that will have access to the vm. Default belong to requester if not specified. Additional users can be added by using a comma(,) as a separator. <br> (e.g. Americas\\firstName_lastName). Only PAC group is accepted for PROD.",
"pattern": "^((Americas|Asia-Pacific|Europe)\\\\.[a-zA-Z0-9_.%]*[*,]?[\\s]*)*$"
},
"NetworkProfile": {
"$id": "#/properties/NetworkProfile",
"type": "string",
"enum": [
"APP",
"WEB"
],
"title": "Server Type/Function",
"description": "Web Server is meant to serve static pages e.g. HTML and CSS, while Application Server is responsible for generating dynamic content by executing server side code.",
"default": "",
"examples": [
""
],
"pattern": "^(.*)$"
},
"eDell": {
"$id": "#/properties/eDell",
"title": "Is the VM related to eDell? ",
"type": "boolean",
"default": false
},
"Disks": {
"$id": "#/properties/Disks",
"type": "array",
"title": "Local (Non-OS) Storage. Default OS Drive (C) size is 60GB. The (D) drive is fixed at 20 GB, can use E-Z for additional storage. Can only add an additional 900GB.",
"items": {
"$id": "#/properties/Disks/items",
"type": "object",
"title": " ",
"required": [
"data"
],
"properties": {
"data": {
"$id": "#/properties/Disks/items/properties/data",
"type": "object",
"title": " ",
"required": [
"capacity",
"initial_location"
],
"properties": {
"capacity": {
"$id": "#/properties/Disks/items/properties/data/properties/capacity",
"type": "number",
"title": "Capacity (GB)",
"default": "",
"examples": [
"20"
],
"minimum": 5,
"maximum": 900
},
"initial_location": {
"$id": "#/properties/Disks/items/properties/data/properties/initial_location",
"type": "string",
"title": "Drive Letter",
"default": "E",
"examples": [
"/u02"
],
"description": "Drive Letter of the partition without colon",
"pattern": "^[eE,fF,gG,hH,iI,jJ,kK,lL,mM,nN,oO,pP,qQ,rR,sS,tT,uU,vV,wW,xX,yY,zZ]{1}$",
"validationMessages": {
"pattern": "C,D are reserved use E-Z.",
"required": "C,D are reserved use E-Z."
}
}
}
}
}
}
},
"FILESTORAGE": {
"$id": "#/FileStorage",
"type": "string",
"enum": [
"YES",
"NO"
],
"title": "Add File Storage",
"default": "NO",
"examples": [
""
],
"pattern": "^(.*)$"
}
},
"if": {
"properties": {
"FILESTORAGE": {
"const": "YES"
}
}
},
"then": {
"properties": {
"NASDisk": {
"$id": "#/properties/NASDisk",
"type": "object",
"title": "File Storage",
"required": [
"AppName",
"SizeGB",
"Protocol",
"ShareOwner",
"Function"
],
"properties": {
"Protocol": {
"$id": "#/properties/NASDisk/properties/Protocol",
"type": "string",
"default": "CIFS",
"options": {
"hidden": "true"
}
},
"Function": {
"$id": "#/properties/NASDisks/properties/Function",
"type": "string",
"enum": [
"File",
"Storage",
"Backup",
"App",
"Log",
"Database",
"Repository"
],
"title": "Choose Function for NAS",
"default": "File",
"examples": [
""
],
"pattern": "^(.*)$"
},
"AppName": {
"$id": "#/properties/NASDisk/properties/AppName",
"type": "string",
"title": "App Name",
"default": "",
"description": "Abbreviation or alias of the application name to be prefix to the share name, limit to 10 letters",
"pattern": "^[a-zA-Z]{1,10}$"
},
"SizeGB": {
"$id": "#/properties/NASDisk/properties/SizeGB",
"type": "number",
"title": "Size (GB)",
"default": 5,
"examples": [
5
],
"minimum": 5,
"maximum": 500
},
"ShareOwner": {
"$id": "#/properties/NASDisk/properties/ShareOwner",
"type": "string",
"title": "Share Owner",
"default": "",
"description": "User account with ownership of the share. Group ownership can be specified using the format DOMAIN\\UserName. <br> (e.g. Americas\\firstName_lastName).",
"examples": [
"adms_c_lawlor"
],
"pattern": "^((Americas|Asia-Pacific|Europe)\\\\.[a-zA-Z0-9_.%]*[*,]?[\\s]*)*$"
},
"FC_Members": {
"$id": "#/properties/NASDisk/properties/FC_Members",
"type": "string",
"description": "Comma separated AD groups that will have full control of share."
},
"RW_Members": {
"$id": "#/properties/NASDisk/properties/RW_Members",
"type": "string",
"description": "Comma separated AD groups that will have read/write control of share."
}
}
}
}
},
"else": {}
}
Here was my allOf attempt:
"allOf": [
{
"if": {
"properties": {
"FILESTORAGE": {
"const": "YES"
}
}
},
"then": {
"properties": {
"NASDisk": {
"$id": "#/properties/NASDisk",
"type": "object",
"title": "File Storage",
"required": [
"AppName",
"SizeGB",
"Protocol",
"ShareOwner",
"Function"
],
"properties": {
"Protocol": {
"$id": "#/properties/NASDisk/properties/Protocol",
"type": "string",
"default": "CIFS",
"options": {
"hidden": "true"
}
},
"Function": {
"$id": "#/properties/NASDisks/properties/Function",
"type": "string",
"enum": [
"File",
"Storage",
"Backup",
"App",
"Log",
"Database",
"Repository"
],
"title": "Choose Function for NAS",
"default": "File",
"examples": [
""
],
"pattern": "^(.*)$"
},
"AppName": {
"$id": "#/properties/NASDisk/properties/AppName",
"type": "string",
"title": "App Name",
"default": "",
"description": "Abbreviation or alias of the application name to be prefix to the share name, limit to 10 letters",
"pattern": "^[a-zA-Z]{1,10}$"
},
"SizeGB": {
"$id": "#/properties/NASDisk/properties/SizeGB",
"type": "number",
"title": "Size (GB)",
"default": 5,
"examples": [
5
],
"minimum": 5,
"maximum": 500
},
"ShareOwner": {
"$id": "#/properties/NASDisk/properties/ShareOwner",
"type": "string",
"title": "Share Owner",
"default": "",
"description": "User account with ownership of the share. Group ownership can be specified using the format DOMAIN\\UserName. <br> (e.g. Americas\\firstName_lastName).",
"examples": [
"adms_c_lawlor"
],
"pattern": "^((Americas|Asia-Pacific|Europe)\\\\.[a-zA-Z0-9_.%]*[*,]?[\\s]*)*$"
},
"FC_Members": {
"$id": "#/properties/NASDisk/properties/FC_Members",
"type": "string",
"description": "Comma separated AD groups that will have full control of share."
},
"RW_Members": {
"$id": "#/properties/NASDisk/properties/RW_Members",
"type": "string",
"description": "Comma separated AD groups that will have read/write control of share."
}
}
}
}
},
"else": {
}
},
{
"if": {
"properties": {
"Instances": {
"minimum": "1"
}
}
},
"then": {
"properties": {
"StartIndex": {
"$id": "#/properties/StartIndex",
"hidden": true,
"default": "1",
"examples": [
"1"
],
"pattern": "^(.*)$",
"title": "Start Index for these VMs",
"description": "The starting sequence number for this set of servers",
"type": "number",
"minimum": 0
}
}
},
"else": {
"properties": {
"StartIndex": {
"$id": "#/properties/StartIndex",
"default": "",
"examples": [
"1"
],
"pattern": "^(.*)$",
"title": "Start Index for these VMs",
"description": "The starting sequence number for this set of servers",
"type": "number",
"minimum": 0
}
}
}
}
]
UPDATE: So I actually figure this out using nested properties as shown here
"isMultiDropdown": {
"title": "",
"$id": "#/properties/isMultiDropdown",
"required": [
"isMulti"
],
"type": "object",
"if": {
"properties": {
"isMulti": {
"const": "YES"
}
}
},
"then": {
"properties": {
"StartIndex": {
"$id": "#/properties/StartIndex",
"default": "",
"examples": [
"1"
],
"pattern": "^(.*)$",
"title": "Start Index for these VMs",
"description": "The starting sequence number for this set of servers",
"type": "number",
"minimum": 0
}
}
},
"properties": {
"isMulti": {
"$id": "#/properties/isMultiDropdown/isMulti",
"enum": [
"YES",
"NO"
],
"title": "Are you provisioning multiple instances?",
"default": "NO",
"examples": [
""
],
"pattern": "^(.*)$",
"type": "string"
}
}
}
```

Related

JsonSchema: Validate an item in the List based on value of another attribute

I have a requirement to put a check on value based on certain other attribute value in same object (both of them are inside list ) e.g paymentType is SHOPPING_CARDS, I want to mandate few attributes i.e paymentReference1 , paymentReference2 otherwise not. I have added this check , I am passing paymentType as CASH but still getting false error that required attributes are missing , though paymentId1 is being passed in all the items in list. Can someone please help to find out what I am doing wrong?
Failing Impl
Error
$.paymentReference1: is missing but it is required
Update- As per one comment below , I have moved if/else in schema where this check is required but now issue is it is not raising any alarm when we remove paymentRef.
Json Schema
{
"type": "object",
"required": [
"payment"
],
"properties": {
"payment": {
"$id": "#root/payment",
"title": "Payment",
"type": "object",
"required": [
"requestId",
"requestTimestamp",
"requestType",
"orderNo",
"orderDate",
"enterpriseCode",
"documentType",
"entryType",
"paymentRuleId",
"membershipNo",
"orderTotalAmount",
"priceInfo",
"paymentMethods",
"createServiceId"
],
"properties": {
"requestId": {
"$id": "#root/payment/requestId",
"title": "Requestid",
"type": "string",
"default": "",
"examples": [
"263e9575-09ea-45dc-b1d9-87ec7888d3ff"
],
"pattern": "^.*$"
},
"requestTimestamp": {
"$id": "#root/payment/requestTimestamp",
"title": "Requesttimestamp",
"type": "string",
"default": "",
"examples": [
"2021-12-01T07:16:31Z"
],
"pattern": "^.*$"
},
"requestType": {
"$id": "#root/payment/requestType",
"title": "Requesttype",
"type": "string",
"default": "",
"examples": [
"CREATE_ORDER/ADDITION"
],
"pattern": "^.*$"
},
"orderNo": {
"$id": "#root/payment/orderNo",
"title": "Orderno",
"type": "string",
"default": "",
"examples": [
"9762909359"
],
"pattern": "^.*$"
},
"orderDate": {
"$id": "#root/payment/orderDate",
"title": "Orderdate",
"type": "string",
"default": "",
"examples": [
"2022-05-09T14:01:21.000+0000"
],
"pattern": "^.*$"
},
"enterpriseCode": {
"$id": "#root/payment/enterpriseCode",
"title": "Enterprisecode",
"type": "string",
"default": "",
"examples": [
"SAMS"
],
"pattern": "^.*$"
},
"documentType": {
"$id": "#root/payment/documentType",
"title": "Documenttype",
"type": "string",
"default": "",
"examples": [
"0001"
],
"pattern": "^.*$"
},
"entryType": {
"$id": "#root/payment/entryType",
"title": "Entrytype",
"type": "string",
"default": "",
"examples": [
"ONLINE"
],
"pattern": "^.*$"
},
"paymentRuleId": {
"$id": "#root/payment/paymentRuleId",
"title": "Paymentruleid",
"type": "string",
"default": "",
"examples": [
"SAMS"
],
"pattern": "^.*$"
},
"membershipNo": {
"$id": "#root/payment/membershipNo",
"title": "Membershipno",
"type": "string",
"default": "",
"examples": [
"10142100469959798"
],
"pattern": "^.*$"
},
"orderTotalAmount": {
"$id": "#root/payment/orderTotalAmount",
"title": "Ordertotalamount",
"type": "string",
"default": "",
"examples": [
""
],
"pattern": "^.*$"
},
"priceInfo": {
"$id": "#root/payment/priceInfo",
"title": "Priceinfo",
"type": "object",
"required": [
"currency",
"enterpriseCurrency"
],
"properties": {
"currency": {
"$id": "#root/payment/priceInfo/currency",
"title": "Currency",
"type": "string",
"default": "",
"examples": [
"USD"
],
"pattern": "^.*$"
},
"enterpriseCurrency": {
"$id": "#root/payment/priceInfo/enterpriseCurrency",
"title": "Enterprisecurrency",
"type": "string",
"default": "",
"examples": [
"USD"
],
"pattern": "^.*$"
}
}
},
"paymentMethods": {
"$id": "#root/payment/paymentMethods",
"title": "Paymentmethods",
"type": "array",
"default": [
],
"items": {
"$id": "#root/payment/paymentMethods/items",
"title": "Items",
"type": "object",
"required": [
"sequenceNo",
"customerPONo",
"displaySvcNo",
"maxChargeLimit",
"paymentType",
"svcNo",
"unlimitedCharges",
"paymentDetails"
],
"properties": {
"sequenceNo": {
"$id": "#root/payment/paymentMethods/items/sequenceNo",
"title": "Sequenceno",
"type": "string",
"default": "",
"examples": [
"1"
],
"pattern": "^.*$"
},
"customerPONo": {
"$id": "#root/payment/paymentMethods/items/customerPONo",
"title": "Customerpono",
"type": "string",
"default": "",
"examples": [
"0"
],
"pattern": "^.*$"
},
"displaySvcNo": {
"$id": "#root/payment/paymentMethods/items/displaySvcNo",
"title": "Displaysvcno",
"type": "string",
"default": "",
"examples": [
"719"
],
"pattern": "^.*$"
},
"maxChargeLimit": {
"$id": "#root/payment/paymentMethods/items/maxChargeLimit",
"title": "Maxchargelimit",
"type": "number",
"examples": [
159.27
],
"default": 0.0
},
"paymentId1": {
"$id": "#root/payment/paymentMethods/items/paymentReference1",
"type": "string",
"default": "",
"examples": [
"T4543F/JCgkLnk6OT4qJ/hc+sg=="
],
"pattern": "^.*$"
},
"paymentId2": {
"$id": "#root/payment/paymentMethods/items/paymentReference2",
"title": "Paymentreference2",
"type": "string",
"default": "",
"examples": [
"ebdbbf2f-aec1-414a-a8b7-ec33de993c02"
],
"pattern": "^.*$"
},
"paymentId3": {
"$id": "#root/payment/paymentMethods/items/paymentReference3",
"title": "Paymentreference3",
"type": "string",
"default": "",
"examples": [
"Regular"
],
"pattern": "^.*$"
},
"paymentType": {
"$id": "#root/payment/paymentMethods/items/paymentType",
"title": "Paymenttype",
"type": "string",
"default": "",
"examples": [
"CASH"
],
"pattern": "^.*$"
},
"svcNo": {
"$id": "#root/payment/paymentMethods/items/svcNo",
"title": "Svcno",
"type": "string",
"default": "",
"examples": [
"6194995892193728"
],
"pattern": "^.*$"
},
"unlimitedCharges": {
"$id": "#root/payment/paymentMethods/items/unlimitedCharges",
"title": "Unlimitedcharges",
"type": "string",
"default": "",
"examples": [
"N"
],
"pattern": "^.*$"
},
"paymentDetails": {
"$id": "#root/payment/paymentMethods/items/paymentDetails",
"title": "Paymentdetails",
"type": "object",
"required": [
"internalReturnCode",
"authorizationID",
"authCode",
"internalReturnMessage",
"processedAmount",
"chargeType",
"holdAgainstBook",
"authTime",
"requestAmount",
"authReturnMessage",
"authReturnCode",
"requestId"
],
"properties": {
"internalReturnCode": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/internalReturnCode",
"title": "Internalreturncode",
"type": "string",
"default": "",
"examples": [
""
],
"pattern": "^.*$"
},
"authorizationID": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/authorizationID",
"title": "Authorizationid",
"type": "string",
"default": "",
"examples": [
"940799"
],
"pattern": "^.*$"
},
"authCode": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/authCode",
"title": "Authcode",
"type": "string",
"default": "",
"examples": [
"000"
],
"pattern": "^.*$"
},
"internalReturnMessage": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/internalReturnMessage",
"title": "Internalreturnmessage",
"type": "string",
"default": "",
"examples": [
""
],
"pattern": "^.*$"
},
"processedAmount": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/processedAmount",
"title": "Processedamount",
"type": "string",
"default": "",
"examples": [
"159.27"
],
"pattern": "^.*$"
},
"chargeType": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/chargeType",
"title": "Chargetype",
"type": "string",
"default": "",
"examples": [
"CHARGE"
],
"pattern": "^.*$"
},
"holdAgainstBook": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/holdAgainstBook",
"title": "Holdagainstbook",
"type": "string",
"default": "",
"examples": [
"Y"
],
"pattern": "^.*$"
},
"authTime": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/authTime",
"title": "Authtime",
"type": "string",
"default": "",
"examples": [
"2022-06-08T23:21:49"
],
"pattern": "^.*$"
},
"requestAmount": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/requestAmount",
"title": "Requestamount",
"type": "string",
"default": "",
"examples": [
"159.27"
],
"pattern": "^.*$"
},
"authReturnMessage": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/authReturnMessage",
"title": "Authreturnmessage",
"type": "string",
"default": "",
"examples": [
""
],
"pattern": "^.*$"
},
"authReturnCode": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/authReturnCode",
"title": "Authreturncode",
"type": "string",
"default": "",
"examples": [
"000"
],
"pattern": "^.*$"
},
"requestId": {
"$id": "#root/payment/paymentMethods/items/paymentDetails/requestId",
"title": "Requestid",
"type": "string",
"default": "",
"examples": [
"6bf404e0-d756-4247-9030-669c83d0d825"
],
"pattern": "^.*$"
}
}
}
}
},
"if": {
"properties": {
"paymentType": {
"enum": [
"CASH"
]
}
}
},
"then": {
"required": [
"paymentId1"
]
}
},
"createServiceId": {
"$id": "#root/payment/createServiceId",
"title": "Createserviceid",
"type": "string",
"default": "",
"examples": [
"PRE_FULFILLMENT"
],
"pattern": "^.*$"
}
}
}
}
}
Your use of if/then is fine, it's just in the wrong place. You need to move it into the schema that has the properties you're working with.
{
"type": "object",
"properties": {
"payment": {
"type": "object",
"properties": {
"paymentMethods": {
"type": "array",
"items": {
"type": "object",
"properties": {
"paymentId1": { "type": "string" },
"paymentId2": { "type": "string" },
"paymentType": { "type": "string" }
},
"if": {
"properties": {
"paymentType": { "enum": ["CASH"] }
}
},
"then": { "required": ["paymentId1","paymentId2"] }
}
}
}
}
}
}

JSON Schema Validation - required fields depending on boolean value

I have looked at many other posts, but can't find a solution to my problem.
I'm trying to validate the following scenario through a json schema:
If isRetired = false then retirementAge, salary and salaryFreq are additionally required.
I have tried the below in addition to a oneOf with 2 schemas to include all the required fields for isRetired = true/false but that never worked either.
Any suggestions would be greatly appreciated.
Thanks in advance!
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"required": ["input"],
"properties": {
"input": {
"$id": "#root/input",
"title": "Input",
"type": "object",
"required": ["persons"],
"properties": {
"persons": {
"$id": "#root/input/persons",
"title": "Persons",
"type": "array",
"default": [],
"minItems": 1,
"maxItems": 2,
"items": {
"$id": "#root/input/persons/items",
"title": "Items",
"type": "object",
"required": [
"gender",
"age",
"isRetired",
"superConcContPercentage",
"totalSuper",
"riskGrowthPercentage",
"includeAgePension"
],
"properties": {
"firstName": {
"$id": "#root/input/persons/items/firstName",
"title": "Firstname",
"type": "string",
"default": "",
"examples": ["Joe"],
"pattern": "^.*$"
},
"lastName": {
"$id": "#root/input/persons/items/lastName",
"title": "Lastname",
"type": "string",
"default": "",
"examples": ["Bloggs"],
"pattern": "^.*$"
},
"gender": {
"$id": "#root/input/persons/items/gender",
"title": "Gender",
"type": "string",
"default": "",
"examples": ["male"],
"pattern": "^.*$"
},
"age": {
"$id": "#root/input/persons/items/age",
"title": "Age",
"type": "integer",
"examples": [27],
"default": 0,
"minimum": 18,
"maximum": 110
},
"isRetired": {
"$id": "#root/input/persons/items/isRetired",
"title": "Isretired",
"type": "boolean",
"examples": [false],
"default": true
},
"retirementAge": {
"$id": "#root/input/persons/items/retirementAge",
"title": "Retirementage",
"type": "integer",
"examples": [70],
"default": 0,
"minimum": 19,
"maximum": 110
},
"salary": {
"$id": "#root/input/persons/items/salary",
"title": "Salary",
"type": "integer",
"examples": [100000],
"default": 0,
"minimum": 0
},
"salaryFreq": {
"$id": "#root/input/persons/items/salaryFreq",
"title": "Salaryfreq",
"type": "integer",
"examples": [12],
"default": 0
},
"superConcContPercentage": {
"$id": "#root/input/persons/items/superConcContPercentage",
"title": "Superconccontpercentage",
"type": "integer",
"examples": [0],
"default": 0,
"minimum": 0,
"maximum": 100
},
"totalSuper": {
"$id": "#root/input/persons/items/totalSuper",
"title": "Totalsuper",
"type": "integer",
"examples": [10000],
"default": 0,
"minimum": 0
},
"riskGrowthPercentage": {
"$id": "#root/input/persons/items/riskGrowthPercentage",
"title": "Riskgrowthpercentage",
"type": "integer",
"examples": [50],
"default": 0,
"minimum": 0,
"maximum": 100
},
"includeAgePension": {
"$id": "#root/input/persons/items/includeAgePension",
"title": "Includeagepension",
"type": "boolean",
"examples": [false],
"default": true
}
}
},
"if": {
"properties": {
"isRetired": {
"const": false
}
}
},
"then": {
"required": [
"retirementAge",
"salary",
"salaryFreq"
]
},
"else": {
"required": []
}
}
}
}
}
}
I discovered your question while trying to figure this exact use case out for myself. Here is what I came up with:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"trigger": { "type": "boolean" },
"dependentProp": { "type": "string" }
},
"if": {
"properties": {
"trigger": {
"type": "boolean",
"enum": [false]
}
}
},
"then": { "required": ["dependentProp"] }
}
There might be a cleaner way to do it but it worked for me so I'm going with it and moving on haha.
I ended up with the below to satisfy the use case:
"if": {
"properties": {
"isRetired": {
"const": false
}
}
},
"then": {
"properties": {
"salary": {
"$id": "#root/input/persons/items/salary",
"title": "Salary",
"type": "integer",
"examples": [100000],
"default": 0,
"minimum": 0
},
"salaryFreq": {
"$id": "#root/input/persons/items/salaryFreq",
"title": "Salaryfreq",
"type": "integer",
"examples": [12],
"default": 0
}
},
"required": ["salary", "salaryFreq"]
}

JSON Schema for restricting block occurrences inside of an array

Probably there are many question on JSON schema, however, I couldn't find an answer I was looking for.
I have a JSON message where the block inside FlagDetails array can come a max of 300 times. How do I restrict this using the schema which I have created below so that Time and UID can come max of 300 but max occurrences is 1 per array block.
JSON body:
{
"SData": {
"IData": {
"IDatas": {
"Flag": "Yes",
"FlagDetails": [
{
"Time": "2012-07-06 09:30:00",
"UID": 1234567
},
{
"Time": "2012-07-06 09:30:00",
"UID": 1234567
}
]
}
}
}
}
JSON schema:
{
"definitions": {},
"type": "object",
"required": [
"SData"
],
"properties": {
"SData": {
"title": "SData",
"type": "object",
"required": [
"IData"
],
"properties": {
"IData": {
"title": "IData",
"type": "object",
"required": [
"IDatas"
],
"properties": {
"IDatas": {
"title": "IDatas",
"type": "object",
"required": [
"Flag"
],
"properties": {
"Flag": {
"title": "Flag",
"type": "string",
"default": "",
"examples": [
"Yes"
],
"minLength": 2,
"maxLength": 3,
"minOccurs": 0,
"maxOccurs": 1,
"pattern": "^.*$"
},
"FlagDetails": {
"title": "FlagDetails",
"type": "array",
"default": [],
"items": {
"title": "Items",
"type": "object",
"properties": {
"Time": {
"title": "Time",
"type": "string",
"default": "",
"examples": [
"2012-07-06 09:30:00"
],
"minOccurs": 0,
"pattern": "^.*$"
},
"UID": {
"title": "UId",
"type": "integer",
"default": "",
"examples": [
"12345678912"
],
"minLength": 4,
"maxLength": 12,
"minOccurs": 0,
"pattern": "^.*$"
}
}
}
}
}
}
}
}
}
}
}
}
The answer to this is "minItems" & "maxItems". I have used those and it works perfectly.
"FlagDetails": {
"title": "FlagDetails",
"type": "array",
**"minItems": 0,
"maxItems": 300,**
"default": []

Validate Json schema based on the value specified for a property

I have a Json request having the below data and a corresponding json schema for it
With this request, I want to make a few fields as required depending on the mode
Say if mode is 1, then I want the fields a and b in obj1 to be required and field x in obj3 as required.
Now if the mode is 2, I would want fields p, q and r in obj2 to be required, fields a and c in obj1 as required and field y in obj3 as required.
Next if the mode is 3, I want only fields a and c as required
Json request
{
"mode": "1",
"obj1": {
"a": 12,
"b": "test",
"c": "18 June 2019"
},
"obj2": {
"p": 100,
"q": "new",
"r": "19 June 2019",
"s" : "test2"
},
"obj3": {
"x": 12,
"y": "test3"
}
}
**Json schema**
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"properties": {
"mode": {
"$id": "#/properties/mode",
"type": "string",
"examples": [
"1"
]
},
"obj1": {
"$id": "#/properties/obj1",
"type": "object",
"title": "The Obj 1 Schema",
"properties": {
"a": {
"$id": "#/properties/obj1/properties/a",
"type": "integer",
"examples": [
12
]
},
"b": {
"$id": "#/properties/obj1/properties/b",
"type": "string",
"examples": [
"test"
]
},
"c": {
"$id": "#/properties/obj1/properties/c",
"type": "string",
"examples": [
"18 June 2019"
]
}
}
},
"obj 2": {
"$id": "#/properties/obj2",
"type": "object",
"title": "The Obj 2 Schema",
"properties": {
"p": {
"$id": "#/properties/obj2/properties/p",
"type": "integer",
"examples": [
100
]
},
"q": {
"$id": "#/properties/obj2/properties/q",
"type": "string",
"examples": [
"new"
]
},
"r": {
"$id": "#/properties/obj2/properties/r",
"type": "string",
"examples": [
"19 June 2019"
]
},
"s": {
"$id": "#/properties/obj2/properties/s",
"type": "string",
"examples": [
"test2"
]
}
}
},
"obj 3": {
"$id": "#/properties/obj3",
"type": "object",
"title": "The Obj 3 Schema",
"properties": {
"x": {
"$id": "#/properties/obj3/properties/x",
"type": "integer",
"examples": [
12
]
},
"y": {
"$id": "#/properties/obj3/properties/y",
"type": "string",
"examples": [
"test3"
]
}
}
}
}
}
EDIT - Changed the schema to validate based on the suggestion by #gregsdennis
JSON SCHEMA
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"properties": {
"mode": {
"$id": "#/properties/mode",
"type": "string",
"examples": [
"1"
]
},
"obj1": {
"$id": "#/properties/obj1",
"type": "object",
"title": "The Obj 1 Schema",
"properties": {
"a": {
"type": "integer",
"examples": [
12
]
},
"b": {
"type": "string",
"examples": [
"test"
]
},
"c": {
"type": "string",
"examples": [
"18 June 2019"
]
}
}
},
"obj 2": {
"$id": "#/properties/obj2",
"type": "object",
"title": "The Obj 2 Schema",
"properties": {
"p": {
"type": "integer",
"examples": [
100
]
},
"q": {
"type": "string",
"examples": [
"new"
]
},
"r": {
"type": "string",
"examples": [
"19 June 2019"
]
},
"s": {
"type": "string",
"examples": [
"test2"
]
}
}
},
"obj 3": {
"$id": "#/properties/obj3",
"type": "object",
"title": "The Obj 3 Schema",
"properties": {
"x": {
"type": "integer",
"examples": [
12
]
},
"y": {
"type": "string",
"examples": [
"test3"
]
}
}
}
},
"oneOf": [
{
"properties": {
"mode": {"const": 1},
"obj1": {"required": ["a","b"]},
"obj3": {"required": ["x"]}
}
},
{
"properties": {
"mode": {"const": 2},
"obj2": {"required": ["p","q","r"]},
"obj1": {"required": ["a","c"]},
"obj3": {"required": ["y"]}
}
}
]
}
So, in brief, irrespective of how many modes, fields or objects I have, I would like only a few selected fields from different objects to be required at a given time for a particular mode.
Can anyone please suggest any solutions to achieve this? Is it possible to have such validations in the json schema?
What you want is an oneOf where each subschema gives a valid state for each of obj* properties. Each state would be something like this:
{
"properties": {
"mode": {"const": 1},
"obj1": {"required": ["a","b"]},
"obj3": {"required": ["x"]}
}
}
Create one of these for each of the states you listed in your question, and throw them all in a oneOf that lives at the root.
You could do this with if/then/else, but for this case, I'd prefer the oneOf to avoid nesting.
Also, I notice that you have a lot of superfluous $ids in the middle that are just specifying their location within the schema. You want the one at the root, but you don't need the others. Implementations can work out these kinds of location-based references trivially.

JSON Schema Draft-07 if-then-else required field validation does not seem correct

Using Draft-07
What I got was
valid JSON
What error I expected from audit object was
directory: String length must be greater than or equal to 2
Tried two different validators with same results
https://www.jsonschemavalidator.net/
GoLang https://github.com/xeipuuv/gojsonschema
This is my schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ISAM-Wrapper",
"description": "Validate isam wrapper json",
"type": "object",
"properties": {
"directory": {
"description": "path to location of isam file",
"type": "string",
"minLength": 2
},
"isamFile": {
"description": "isam database file",
"type": "string",
"minLength": 4
},
"isamIndex": {
"description": "isam index file",
"type": "string",
"minLength": 4
},
"port": {
"description": "port number for REST listener",
"type": "integer",
"minimum": 60410,
"maximum": 69999
},
"actions": {
"description": "Which operations are supported",
"type": "object",
"items": {
"properties": {
"create": {
"type": "boolean"
},
"read": {
"type": "boolean"
},
"update": {
"type": "boolean"
},
"delete": {
"type": "boolean"
}
}
},
"required": [
"create",
"read",
"update",
"delete"
]
},
"fields": {
"description": "each object describes one field of the isam file",
"type": "array",
"minItems": 1,
"items": {
"title": "field",
"description": "field schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"ordinal": {
"type": "integer",
"minimum": 0
},
"offset": {
"type": "integer",
"minimum": 0
},
"length": {
"type": "integer",
"minimum": 1
},
"dataType": {
"enum": [
"uchar",
"ulong",
"long",
"uint",
"int",
"ushort",
"short"
]
}
},
"required": [
"name",
"ordinal",
"offset",
"length",
"dataType"
]
}
},
"audit": {
"description": "input needed to enable and configure isam auditing",
"type": "object",
"items": {
"properties": {
"enable": {
"enum": [
true,
false
]
},
"directory": {
"type": "string",
"minLength": 2
},
"fileName": {
"type": "string",
"minLength": 4
},
"workDirectory": {
"type": "string",
"minLength": 2
},
"archiveDirectory": {
"type": "string",
"minLength": 2
},
"interval": {
"type": "integer",
"minimum": 1
},
"byteThreshold": {
"type": "integer",
"minimum": 1048576,
"maximum": 1073741824
}
}
},
"required": [
"enable"
],
"if": {
"not": {
"properties": {
"enable": {
"enum": [
false
]
}
}
}
},
"then": {
"required": [
"directory",
"fileName",
"workDirectory",
"archiveDirectory",
"interval",
"byteThreshold"
]
}
}
},
"required": [
"directory",
"isamFile",
"isamIndex",
"port",
"actions",
"fields",
"audit"
]
}
This is my JSON
{
"directory": "./",
"isamFile": "isam.dat",
"isamIndex": "isam.idx",
"port": 60410,
"actions": {
"create": true,
"read": true,
"update": true,
"delete": true
},
"fields": [
{
"name": "F1",
"ordinal": 0,
"offset": 0,
"length": 4,
"dataType": "ulong"
},
{
"name": "F2",
"ordinal": 1,
"offset": 4,
"length": 4,
"dataType": "ulong"
}
],
"audit": {
"enable": true,
"directory": "",
"fileName": "file",
"workDirectory": "./work",
"archiveDirectory": "./archive",
"interval": 5,
"byteThreshold": 1500000
}
}
This issue you have is that your schema is invalid. For both actions and audit you specify these as objects but you don't provide any properties. What you do do, however, is specify an items key (which does nothing here - that's a key on an array) which contains the properties.
Once you correct this error, the schema behaves as you intend, see https://repl.it/repls/BlankWellmadeFrontpage