I have a HTTP response body json object, of which the name of the top level property (${id}) is changing in each response. I am wondering how to describe it in json schema?
{
"${id}": {
"option": {
"name": "value"
}
}
}
It could be:
{
"12874349: {
"option": {
"name": "value"
}
}
}
or
{
"12874349: {
"option": {
"name": "value"
}
},
"12874350: {
"option": {
"name": "value"
}
}
}
You could either use additionalProperties:
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"option": {...}
}
}
}
or patternProperties:
{
"type": "object",
"patternProperties": {
"^[1-9][0-9]*$": { // regex for a positive integer
"type": "object",
"properties": {
"option": {...}
}
}
}
}
You don't mention it in your question, but if you wanted to place limits on the number of top-level properties, you can use minProperties/maxProperties, e.g.:
{
"type": "object",
"minProperties": 1, // at least one property
"maxProperties": 5, // no more than five at a time
"patternProperties": {
"^[1-9][0-9]*$": {...}
}
}
Related
I could not find any examples of this so I'm assuming it's not possible, but want to confirm.
I have a main schema that references other schemas:
https://www.jsonschemavalidator.net/s/4aLvXa4I
{
"$defs": {
"mainSchema": {
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"type": "object",
"properties": {
"objectOne": {
"$ref": "#/$defs/objectOne"
},
"objectTwo": {
"$ref": "#/$defs/objectTwo"
}
}
},
"objectOne": {
"type": "object",
"properties": {
"checkThisValue": {
"type": "string",
"enum": [
"one",
"two",
"three"
]
}
}
},
"objectTwo": {
"type": "object",
"properties": {
"whenSettingThisValue": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
}
}
}
},
"$ref": "#/$defs/mainSchema"
}
I want to define this rule:
IF objectOne.checkThisValue == one
THEN objectTwo.whenSettingThisValue MUST == A
Same for two=>B and three=>C
Is this possible somehow? How do I reference objectOne properties inside of objectTwo?
Edit
I tried to create an if rule for objectTwo that references objectOne here, but my syntax is wrong because it's not working. whenSettingThisValue is set to C and it's saying valid when it should be invalid: https://www.jsonschemavalidator.net/s/NNjEIhWW
"objectTwo": {
"type": "object",
"properties": {
"whenSettingThisValue": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
}
},
"if": {
"properties": {
"objectOne": {
"checkThisValue": {
"const": "one"
}
}
}
},
"then": {
"properties": {
"objectTwo": {
"whenSettingThisValue": {
"const": "A"
}
}
}
}
}
},
I also tried using a oneOf rule in mainSchema where both the subschemas are used, but it is not working either (this example should be invalid): https://www.jsonschemavalidator.net/s/WkmMasDC
"mainSchema": {
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"type": "object",
"properties": {
"objectOne": {
"$ref": "#/$defs/objectOne"
},
"objectTwo": {
"$ref": "#/$defs/objectTwo"
}
},
"oneOf": [
{
"type": "object",
"properties": {
"objectOne": {
"checkThisValue": {
"const": "one"
}
},
"objectTwo": {
"whenSettingThisValue": {
"const": "A"
}
}
}
}
]
},
Solution
Per answer my OneOf rule was malformed. This correctly checks a value in one object is set in response to another. I thought because I was referencing them in another schema with $ref I would have to do something special, but I don't.
https://www.jsonschemavalidator.net/s/HcVhrShk
"oneOf": [
{
"type": "object",
"properties": {
"objectOne": {
"properties": {
"checkThisValue": {
"const": "one"
}
}
},
"objectTwo": {
"properties": {
"whenSettingThisValue": {
"const": "A"
}
}
}
}
},
{
"type": "object",
"properties": {
"objectOne": {
"properties": {
"checkThisValue": {
"const": "two"
}
}
},
"objectTwo": {
"properties": {
"whenSettingThisValue": {
"const": "B"
}
}
}
}
}
]
},
Yes you can. There is an if/then/else construct which takes schemas as its arguments, so you can define a rule "if property A exists with value X, then property B must exist with value Y" etc.
There are some examples here:
https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else
edit:
in your re-edit, change the oneOf clause to this:
"oneOf": [
{
"type": "object",
"properties": {
"objectOne": {
"properties": {
"checkThisValue": {
"const": "one"
}
}
}
}
},
{
"type": "object",
"properties": {
"objectTwo": {
"properties": {
"whenSettingThisValue": {
"const": "A"
}
}
}
}
}
]
I'm trying to use jsonschema to validate some simple json. I have the following:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"outputs": {
"type": "object",
"properties": {
"ANYSTRING": {
"type": "string",
"properties": {
"label": { "type": "string" },
"otherLabel": { "type": "string" }
}
}
}
}
}
}
Essentially, I want any of the following to be valid:
{
"outputs": {
"this is a sample string": { "label": "test" },
"another string": { },
"and one last one": { "otherLabel": "dummy" }
}
}
(How) Can I have this wildcard string property denoted above as "ANYSTRING"?
I suppose you could use additionalProperties. Side note: a thing of type “string” can’t have properties, but “object” can.
"outputs": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"label": { "type": "string" }
}
}
}
Shawn Silverman (JsonSchema Slack channel)
I have following JSON schema
{
"type": "object",
"additionalProperties": true,
"if":
{
"properties":
{
"battery":
{
"type": "object",
"additionalProperties": false,
"minLength":1,
"properties":
{
"cell_composition":
{
"type": "object",
"additionalProperties": false,
"properties":
{
"value":
{
"enum": ["lithium", "lithium_cobalt"]
}
}
}
}
}
}
} ,
"then":
{
"required": ["number_of_lithium_ion_cells"]
}
}
Below is the JSON data
{
"battery123":
{
"cell_composition":
{
"value": "lithium_polymer"
}
}
}
I got below error
Message:
Required properties are missing from object:
number_of_lithium_ion_cells. Schema path:
#/then/required
Actually when "battery" attribute exist then it works fine.
when "battery" attribute does not exist it should give above mentioned error.
How can I add above condition then it will works on both above mentioned cases.
I have checked your both schemas with JavaScript (see snipet below) and the result is: your both schemas are absolutelly OK. You have to find your mistake not in JSON schemas.
var jObj1 =
{
"type": "object",
"additionalProperties": true,
"if":
{
"properties":
{
"battery":
{
"type": "object",
"additionalProperties": false,
"minLength":1,
"properties":
{
"cell_composition":
{
"type": "object",
"additionalProperties": false,
"properties":
{
"value":
{
"enum": ["lithium", "lithium_cobalt"]
}
}
}
}
}
}
} ,
"then":
{
"required": ["number_of_lithium_ion_cells"]
}
}
var test1 = JSON.parse(JSON.stringify(jObj1));
console.log(test1);
var jObj2 =
{
"battery123":
{
"cell_composition":
{
"value": "lithium_polymer"
}
}
}
var test2 = JSON.parse(JSON.stringify(jObj2));
console.log(test2);
I am wondering how could I validate the "haha" in a sub-property with a random name?
{
"shipping_address": {
"randomName1":{
"haha":"ddd"},
"randomName2":{
"haha":"ddd"},
"randomName3":{
"haha":"ddd"},
}
}
I have tried to simply use allOf, but mine does not work:
{
"$schema": "http://json-schema.org/draft-6/schema#",
"type": "object",
"properties": {
"shipping_address": {
"allOf": [
{ "properties":
{ "haha": { "type": "integer" } }
}
]
}
}
}
You can have a try here: https://www.jsonschemavalidator.net/
Use patternProperties
{
"$schema": "http://json-schema.org/draft-6/schema#",
"type": "object",
"properties": {
"shipping_address": {
"patternProperties": {
"^.*$": {
"properties": {
"haha":{
"type":"integer"
}
}
}
}
}
}
}
As vearutop commented, the improved version:
{
"$schema": "http://json-schema.org/draft-6/schema#",
"type": "object",
"properties": {
"shipping_address": {
"additionalProperties":{
"properties":{
"haha":{
"type":"integer"
}
}
}
}
}
}
I need to build a json schema (draft 4) that requires a property based on the presence of a property in another nested object. I already searched and tried a lot of things (anyOf, oneOf, not, dependencies) with no luck.
Maybe this is not possible to in json schema?
This is my simplified schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": {
"type": "object",
"properties": {
"total": { "type": "string" }
}
}
}
}
}
}
And this is bananas.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["banana"],
"definitions": {
"non-empty-string": {
"type": "string",
"minLength": 1
}
},
"properties": {
"banana": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["unit"],
"properties": {
"unit": { "type": "string" },
"thing": {
"type": "object",
"anyOf": [
{ "required": [ "tax_transfers" ] },
{ "required": [ "tax_retentions" ] }
],
"properties": {
"tax_transfers": {
"type": "object",
"required": ["tax_transfer"],
"properties": {
"tax_transfer": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
},
"tax_retentions": {
"type": "object",
"required": ["tax_retention"],
"properties": {
"tax_retention": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
}
}
}
}
}
}
}
}
I need that when one or more objects in the array have a 'thing' property (at bananas -> banana -> thing).
Then the property 'thing' at (dog -> thing) should be required.
Any help would be really appreciated.
You need two things to express your constraint. The first is "contains" and the other is "implication". I've organized each in the definitions section.
Contains
The items keyword allows us to require that all items in an array are valid against a schema. If it is not true that all of the items in the array are not valid against the schema, then we know that at least one item is valid.
{
"not": {
"items": { "not": { ... schema ... } }
}
}
If you are able to upgrade to JSON Schema draft-06, a contains keyword was added to make this much easier.
{
"contains": { ... schema ... }
}
Implication
Implication allows you to do something like a conditional. The condition schema implies the constraint schema if either the condition is true, or the constraint is true (or both are true). It's effectively the same as saying, if the condition is true then the constraint must also be true.
{
"anyOf": [
{ "not": { ... condition schema ... } },
{ ... constraint schema ... }
]
}
JSON Schema draft-07 adds the if-then-else keywords in attempt to address this case better. I personally dislike the way this was done enough that I'll stick with the implication pattern for this kind of thing, but here it is in case you want to try it.
{
"if": { ... schema ... },
"then": { ... schema ... },
"else": { ... schema ... }
}
All together
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": { "type": "object" }
}
}
},
"allOf": [
{ "$ref": "#/definitions/banana-things-implies-dog-things" }
],
"definitions": {
"banana-has-things": {
"properties": {
"dog": {
"properties": {
"bananas": {
"properties": {
"banana": {
"not": {
"items": { "not": { "required": ["things"] } }
}
}
}
}
}
}
}
},
"banana-things-implies-dog-things": {
"anyOf": [
{ "not": { "$ref": "#/definitions/banana-has-things" }},
{
"properties": {
"dog": { "required": ["things"] }
}
}
]
}
}
}