admin管理员组文章数量:1122846
I have the following schema where I am using a choice of one of two subschemas for the payload.
{
"type": "object",
"definitions": {
"XXXTrades": {
"type": "object",
"title": "XXX Trades",
"properties": {
"instrumentTypes": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"oneOf": [
{
"properties": {
"books": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": [
"books"
]
},
{
"properties": {
"tradeLegIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"tradeLegIds"
]
}
],
"additionalProperties": false
},
"YYYYTrades": {
"type": "object",
"title": "YYYY Trades",
"properties": {
"sourceType": {
"type": "string",
"enum": [
"YYYY"
]
},
"folioInstrumentFilter": {
"type": "string"
}
},
"anyOf": [
{
"type": "object",
"title": "YYYY Folios",
"properties": {
"folios": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"folios"
]
},
{
"title": "YYYY Trade Ids",
"type": "object",
"properties": {
"YYYYTradeIds": {
"type": "array",
"items": {
"type": "integer"
}
},
"minItems": 1
},
"required": [
"YYYYTradeIds"
]
}
],
"required": [
"sourceType"
],
"allOf": [
{
"if": {
"properties": {
"folioInstrumentFilter": {
"type": "string"
}
},
"required": [
"folioInstrumentFilter"
]
},
"then": {
"required": [
"folios"
]
}
}
],
"additionalProperties": false
}
},
"anyOf": [
{
"$ref": "#/definitions/YYYYTrades"
},
{
"$ref": "#/definitions/XXXTrades"
}
]
}
However the following payload fails to validate
{
"YYYYTradeIds": [
1
],
"sourceType": "YYYY"
}
with the following validation error
{
"errors": [
{
"instancePath": "",
"schemaPath": "#/definitions/YYYYTrades/additionalProperties",
"keyword": "additionalProperties",
"params": {
"additionalProperty": "YYYYTradeIds"
},
"message": "must NOT have additional properties",
...
...
..
{
"instancePath": "",
"schemaPath": "#/definitions/XXXTrades/oneOf",
"keyword": "oneOf",
"params": {
"passingSchemas": null
},
"message": "must match exactly one schema in oneOf",
...
...
]
}
It seems that the validator AJV8 is failing to determine which of the sub schemas to use when validating the payload. Is there any mechanism to force the parser/validator to apply the correct sub schema?
I tried inlining the schema instead of using definitions, adding conditions on sourceType but it didn't work.. I have been looking for solutions online for a couple of days.
I have the following schema where I am using a choice of one of two subschemas for the payload.
{
"type": "object",
"definitions": {
"XXXTrades": {
"type": "object",
"title": "XXX Trades",
"properties": {
"instrumentTypes": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"oneOf": [
{
"properties": {
"books": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": [
"books"
]
},
{
"properties": {
"tradeLegIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"tradeLegIds"
]
}
],
"additionalProperties": false
},
"YYYYTrades": {
"type": "object",
"title": "YYYY Trades",
"properties": {
"sourceType": {
"type": "string",
"enum": [
"YYYY"
]
},
"folioInstrumentFilter": {
"type": "string"
}
},
"anyOf": [
{
"type": "object",
"title": "YYYY Folios",
"properties": {
"folios": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"folios"
]
},
{
"title": "YYYY Trade Ids",
"type": "object",
"properties": {
"YYYYTradeIds": {
"type": "array",
"items": {
"type": "integer"
}
},
"minItems": 1
},
"required": [
"YYYYTradeIds"
]
}
],
"required": [
"sourceType"
],
"allOf": [
{
"if": {
"properties": {
"folioInstrumentFilter": {
"type": "string"
}
},
"required": [
"folioInstrumentFilter"
]
},
"then": {
"required": [
"folios"
]
}
}
],
"additionalProperties": false
}
},
"anyOf": [
{
"$ref": "#/definitions/YYYYTrades"
},
{
"$ref": "#/definitions/XXXTrades"
}
]
}
However the following payload fails to validate
{
"YYYYTradeIds": [
1
],
"sourceType": "YYYY"
}
with the following validation error
{
"errors": [
{
"instancePath": "",
"schemaPath": "#/definitions/YYYYTrades/additionalProperties",
"keyword": "additionalProperties",
"params": {
"additionalProperty": "YYYYTradeIds"
},
"message": "must NOT have additional properties",
...
...
..
{
"instancePath": "",
"schemaPath": "#/definitions/XXXTrades/oneOf",
"keyword": "oneOf",
"params": {
"passingSchemas": null
},
"message": "must match exactly one schema in oneOf",
...
...
]
}
It seems that the validator AJV8 is failing to determine which of the sub schemas to use when validating the payload. Is there any mechanism to force the parser/validator to apply the correct sub schema?
I tried inlining the schema instead of using definitions, adding conditions on sourceType but it didn't work.. I have been looking for solutions online for a couple of days.
Share Improve this question edited Nov 22, 2024 at 16:19 Jeremy Fiel 3,1792 gold badges11 silver badges25 bronze badges asked Nov 22, 2024 at 10:57 Mohammed Abu SharikhMohammed Abu Sharikh 11 Answer
Reset to default 0You have a common mistake in your schema. additionalProperties: false
and composition keywords such as anyOf
and oneOf
don't play nice together in earlier versions of JSON Schema. I assume you are using draft-07, which is the default AJV 8 implementation.
To make this behavior work correctly, you need to define the keywords in the subschemas at the root, using an empty schema {}
or true
is sufficient.
With if, then
, typically a schema constraint should be used more than just the type
if you have already defined the type
elsewhere. Otherwise, it's a lot of extra processing and syntax for the use case you have, which is to enforce a specific property if another property exists. This can be done with dependencies
.
The updates I've made to your schema,
- define JSON Schema version, this is important for the keyword behavior
- define subschema keywords at the root with
true
- replace
allOf>if>then
constraint withdependencies
- misplaced
minItems
inYYYYTradeIds
subschema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"XXXTrades": {
"type": "object",
"title": "XXX Trades",
"properties": {
"instrumentTypes": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
},
"books": true,
"tradeLegIds": true
},
"oneOf": [
{
"properties": {
"books": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": [
"books"
]
},
{
"properties": {
"tradeLegIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"tradeLegIds"
]
}
],
"additionalProperties": false
},
"YYYYTrades": {
"type": "object",
"title": "YYYY Trades",
"properties": {
"sourceType": {
"type": "string",
"enum": [
"YYYY"
]
},
"folioInstrumentFilter": {
"type": "string"
},
"folios": true,
"YYYYTradeIds": true
},
"anyOf": [
{
"type": "object",
"title": "YYYY Folios",
"properties": {
"folios": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"folios"
]
},
{
"title": "YYYY Trade Ids",
"type": "object",
"properties": {
"YYYYTradeIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"YYYYTradeIds"
]
}
],
"required": [
"sourceType"
],
"dependencies": {
"folioInstrumentFilter": [
"folios"
]
},
"additionalProperties": false
}
},
"anyOf": [
{
"$ref": "#/definitions/YYYYTrades"
},
{
"$ref": "#/definitions/XXXTrades"
}
]
}
If you're interested and willing to move to a newer JSON Schema draft, you can avoid the additionalProperties
issue and duplicate definitions at the root of the schema with the use of a newer keyword, unevaluatedProperties
. This keyword can see into a subschema defined in a composition (allOf, oneOf, anyOf) keyword, unlike additionalProperties
.
A few other changes required for Draft 2020-12
$schema
requires the proper versiondefinitions
is updated to$defs
additionalProperties
is updated tounevaluatedProperties
dependencies
is updated todependentRequired
- duplicate keyword definitions at the root of the schema are no longer required
- Ajv must import a different module to validate Draft 2020-12. This module is included in the common Ajv package.
const Ajv = require('ajv/dist/2020');
const ajv = new Ajv({ strict: false });
let instance = // your json data instance
let schema = // your json schema
try {
const validate = ajv.compile(schema)
const valid = validate(instance)
console.log(results = { valid: valid, error: validate.errors })
} catch ({ message }) {
console.error(message)
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"$defs": {
"XXXTrades": {
"type": "object",
"title": "XXX Trades",
"properties": {
"instrumentTypes": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"oneOf": [
{
"properties": {
"books": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": [
"books"
]
},
{
"properties": {
"tradeLegIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"tradeLegIds"
]
}
],
"unevaluatedProperties": false
},
"YYYYTrades": {
"type": "object",
"title": "YYYY Trades",
"properties": {
"sourceType": {
"type": "string",
"enum": [
"YYYY"
]
},
"folioInstrumentFilter": {
"type": "string"
}
},
"anyOf": [
{
"type": "object",
"title": "YYYY Folios",
"properties": {
"folios": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"folios"
]
},
{
"title": "YYYY Trade Ids",
"type": "object",
"properties": {
"YYYYTradeIds": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
},
"required": [
"YYYYTradeIds"
]
}
],
"required": [
"sourceType"
],
"dependentRequired": {
"folioInstrumentFilter": [
"folios"
]
},
"unevaluatedProperties": false
}
},
"anyOf": [
{
"$ref": "#/$defs/YYYYTrades"
},
{
"$ref": "#/$defs/XXXTrades"
}
]
}
本文标签: jsonschemaJSON Schema anyOf and additionalProperties false failing validationStack Overflow
版权声明:本文标题:jsonschema - JSON Schema: anyOf and additionalProperties: false failing validation - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736304218a1932157.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论