Json schema variable properties - jsonschema

Based some condition my IPV4 can have either 2 or 3 properties but those are required. How to define it. I tried below schema. I get error saying "JSON is valid against more than one schema from 'oneOf'. Valid schema indexes: 0, 1"
"IPv4Type": {
"type": "object",
"oneOf": [
{
"properties": {
"provider-address": {
"type": "string",
"format": "ipv4"
},
"customer-address": {
"type": "string",
"format": "ipv4"
},
"mask": {
"type": "number"
}
},
"required": [
"provider-address",
"customer-address",
"mask"
]
},
{
"properties": {
"provider-address": {
"type": "string",
"format": "ipv4"
},
"mask": {
"type": "number"
}
},
"required": [
"provider-address",
"mask"
]
}
]
}

A few ideas:
you can drop the oneOf , define your JSON in one object, with all 3 properties defined, but adding only "provider-address" and "mask" as required
defining "additionalProperties": false the the 2nd definition under oneOf
replacing oneOf with anyOf

Related

Enum inside the Array is not validting in json-schema

I am validating the json with json_schema.
Allowed values for ghrBillingCode should be only "I9NOT"
expected result should be error as 2nd and 3rd node is not I9NOT but it is validating json as correct.
What is wrong in json-schema i am using
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{
"type": "object",
"properties": {
"invoiceLineInfo": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"ghrBillingCode": {
"type": "string",
"enum": [
"I9NOT"
]
},
"quantity": {
"type": "integer"
}
}
}
]
},
"invoiceNumber": {
"type": "string"
}
}
}
]
}
json:
[
{
"invoiceLineInfo":[
{
"ghrBillingCode":"I9NOT",
"quantity":1
},
{
"ghrBillingCode":"I9NOTRU",
"quantity":2
},
{
"ghrBillingCode":"I9PSUP",
"quantity":1
}
],
"invoiceNumber":"202203010100301"
}
]
In your schema, you have extra brackets [] around the items array type. This means that the enum is checked for the first array element only and your example validates because the first item happens to be "I9NOT".
From your sample document, it seems like you expect the enum to apply to all array elements. To achieve this, simply drop the [] from the items value.
For the array / items syntax, have a look here:
https://json-schema.org/understanding-json-schema/reference/array.html#items

reference multiple types in json schema array

I am trying to define an array property of an object in a json schema v7, but validation isn't working. How can I correctly reference multiple type definitions to be used in an array? Here an array for Directory can contain more directories or routes:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "RootDirectory",
"title": "Directory",
"description": "Build a directory for javascript app routing.",
"type": "object",
"definitions": {
"Route": {
"type": "object",
"description": "A simple endpoint declaration.",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "An endpoint without forward slashes.",
"examples": ["welcome"],
"minLength": 1
},
"variableSuffix": {
"description": "A string that is appended to the path variable name during build.",
"type": "string"
}
},
"required": ["path"]
},
"Directory": {
"type": "object",
"description": "Contains child directories or routes for recursive tree building.",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "An endpoint without forward slashes.",
"examples": ["welcome"],
"minLength": 1
},
"variableSuffix": {
"description": "A string that is appended to the path variable name during build.",
"type": "string"
},
"childNodes": {
"minItems": 1,
"type": "array",
"description": "An array of routes, linkedRoutes, subDirectories, or linkedSubDirectories.",
"contains": {
"type": "object",
"oneOf": [
{"$ref": "#/definitions/Route"},
{"$ref": "#/definitions/Directory"}
]
}
}
},
"required": ["path", "childNodes"]
},
},
"properties": {
"directories":{
"type": "array",
"contains": {
"type": "object",
"allOf": [{"$ref": "#/definitions/Directory"}]
},
"minItems": 1
},
"rootPath": {
"type": "string",
"default": ""
}
},
"required": ["directories"]
}
for instance, this is valid and shouldn't be since it contains an object with invalid properties:
{
"rootPath": "api",
"directories": [
{
"path": "a",
"childNodes": [
{
"path": "a",
"variableSuffix": "s"
},
{
"invalidProperty" : "a"
}
]
}
]
}
Is the problem that the property /directories/0/childNodes/1/invalidProperty should not be permitted? The schema does not state that all the array items in childNodes must be valid -- it only specifies that childNodes must contain a valid item, and item #0 does validate, therefore the overall schema validates.
To assert that all the items in childNodes must be valid, change contains at /definitions/Directory/properties/childNodes/contains to items -- the items keyword specifies a schema that must be validated against all array items, whereas contains only asserts that at least one array item must validate.

Json schema conditional validation configuration - Unsupported keyword(s): ["const"]]

I want to set up the conditional validation in my schema. I saw an example here on SO.
I have a similar setup, where I would like to validate if the field public is set to string "public". If it is set to "public" then I want to make fields description, attachmentUrl and tags required. If the field is not set to "public" then this fields are not required.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Update todo",
"type": "object",
"properties": {
"public": {
"type": "string"
},
"description": {
"type": "string",
"minLength": 3
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true,
"minItems": 1
},
"attachmentUrl": {
"type": "string"
}
},
"anyOf": [
{
"not": {
"properties": {
"public": { "const": "public" }
},
"required": ["public"]
}
},
{ "required": ["description", "tags", "attachmentUrl"] }
],
"additionalProperties": false
}
But, when I try to deploy it like that, I get the following error:
Invalid model specified: Validation Result: warnings : [], errors :
[Invalid model schema specified. Unsupported keyword(s): ["const"]]
The "const" keyword wasn't added until draft 06. You should upgrade to an implementation that supports at least that version.
https://json-schema.org/draft-06/json-schema-release-notes.html#additions-and-backwards-compatible-changes
Otherwise, you can use "enum" with a single value: "enum": ["public"]

Preventing dependent property validation when the parent property does not exist

I am new to JSON schemas. I have a property (property1) that is dependent on another property (property2), which in turn is dependent on a third property (property3). I am trying to figure out how to prevent the schema from validating property1 if property2 doesn't exist. I am using the Python jsonschema module for validating.
I have a simple schema with three properties: species, otherDescription, and otherDescriptionDetail. The rules I'm trying to enforce are:
1) if species = "Human", otherDescription is required.
2) if species = "Human" and otherDescription != "None", otherDescriptionDetail is required.
3) if species != "Human", neither of the other two fields is required.
My test JSON correctly fails validation if species is "Human" and otherDescription doesn't exist, but it also reports that otherDescriptionDetail is a required property even though at this point it shouldn't be because there is no otherDescription value to compare it against. Is it possible to implement this logic with a JSON schema?
This is my schema:
"$schema": "http://json-schema.org/draft-07/schema#",
"$id":"http://example.com/test_schema.json",
"title": "annotations",
"description": "Validates file annotations",
"type": "object",
"properties": {
"species": {
"description": "Type of species",
"anyOf": [
{
"const": "Human",
"description": "Homo sapiens"
},
{
"const": "Neanderthal",
"description": "Cave man"
}
]
},
"otherDescription": {
"type": "string"
},
"otherDescriptionDetail": {
"type": "string"
}
},
"required": [
"species"
],
"allOf": [
{
"if": {
"properties": {
"species": {
"const": "Human"
}
}
},
"then": {
"required": ["otherDescription"]
}
},
{
"if": {
"allOf": [
{
"properties": {
"species": {
"const": "Human"
},
"otherDescription": {
"not": {"const": "None"}
}
}
}
]
},
"then": {
"required": ["otherDescriptionDetail"]
}
}
]
}
My test JSON is:
{
"species": "Human"
}
The output that I want:
0: 'otherDescription' is a required property
The output that I am getting:
0: 'otherDescription' is a required property
1: 'otherDescriptionDetail' is a required property
Any help would be greatly appreciated.
You need to defined otherDescription as a required property insilde allOf. Otherwise allOf block will pass even if otherDescription not available.
"if": {
"allOf": [
{
"properties": {
"species": {
"const": "Human"
},
"otherDescription": {
"not": {"const": "None"}
}
},
"required": ["otherDescription"]
}
]
},
"then": {
"required": ["otherDescriptionDetail"]
}

How do I indicate which "oneOf" API response will use?

I have an API where the basic response of one key will have an array of identifiers. A user may pass an extra parameter so the array will turn to an array of objects from an array of strings (for actual details rather than having to make a separate call).
"children": {
"type": "array",
"items": {
"oneOf": [{
"type": "string",
"description": "Identifier of child"
}, {
"type": "object",
"description": "Contains details about the child"
}]
}
},
Is there a way to indicate that the first type comes by a default and the second via a requested param?
It's not entirely clear to me what you are trying to accomplish with the distinction. Really that sounds like documentation; maybe elaborate in the descriptions of each oneOf subschema.
You could add an additional boolean field at the top level (sibling of children) to indicate whether detailed responses are returned and provide a default value for that field. The next step is to couple the value of the boolean to the type of the array items, which I've done using oneOf.
I'm suggesting something along the lines of:
{
"children": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string",
"description": "Identifier of child",
"pattern": "^([A-Z0-9]-?){4}$"
},
{
"type": "object",
"description": "Contains details about the child",
"properties": {
"age": {
"type": "number"
}
}
}
]
}
},
"detailed": {
"type": "boolean",
"description": "If true, children array contains extra details.",
"default": false
},
"oneOf": [
{
"detailed": {
"enum": [
true
]
},
"children": {
"type": "array",
"items": {
"type": "object"
}
}
},
{
"detailed": {
"enum": [
false
]
},
"children": {
"type": "array",
"items": {
"type": "string"
}
}
}
]
}
The second oneOf places a further requirement on the response object that when "detailed": true the type of items of the "children" array must be "object". This refines the first oneOf restriction that describes the schema of objects in the "children" array.