AJV-帮助了解严格的警告
我有以下JSON架构:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Form Field configuration",
"properties": {
"title": {
"type": "string",
"title": "The field label"
},
"description": {
"type": "string",
"title": "The field description"
},
"presentation": {
"additionalProperties": false,
"type": "object",
"title": "Configuration for the field visual UI",
"properties": {
"inputType": {
"title": "The recommend way to represent the field visually.",
"anyOf": [
{
"const": "text",
"title": "Similar to the HTML `<input>` with text type."
},
{
"const": "number",
"title": "Similar to the HTML `<input>` with number type."
},
{
"const": "money",
"title": "Similar to 'number', dedicated to monetary values."
}
]
},
"currency": {
"title": "For inputType=money. Monetary Currency Code (3 digits)",
"maxLength": 3,
"minLength": 3,
"type": "string"
},
"description": {
"type": "string",
"title": "The field description with HTML"
}
}
},
"$template": {
"type": "string",
"title": "Pass the template URL to a given field"
}
},
"required": ["presentation"],
"allOf": [
{
"$comment": "Extend the base Draft-07 configuration",
"$ref": "http://json-schema.org/draft-07/schema#"
},
{
"$comment": "Add presentation validations only when $template is not present.",
"if": { "required": ["$template"] },
"else": {
"properties": {
"presentation": {
"$ref": "#/$defs/presentation_validations"
}
}
}
},
{
"if": {
"$comment": "If it contains presentation.description, then [root].description is also required.",
"properties": {
"presentation": {
"required": ["description"]
}
}
},
"then": {
"required": ["description"]
}
}
],
"$defs": {
"presentation_validations": {
"allOf": [
{
"required": ["inputType"]
},
{
"if": {
"properties": {
"inputType": { "const": "money" }
},
"required": ["inputType"]
},
"then": {
"required": ["currency"]
},
"else": {
"properties": { "currency": false }
}
}
]
}
}
}
如果我记录严格的模式警告,我会收到以下警告:
strict mode: required property "$template" is not defined at "#/allOf/1/if" (strictRequired)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/0" (strictTypes)
strict mode: required property "inputType" is not defined at "#/$defs/presentation_validations/allOf/0" (strictRequired)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/1/if" (strictTypes)
strict mode: missing type "object" for keyword "properties" at "#/$defs/presentation_validations/allOf/1/if" (strictTypes)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/1/then" (strictTypes)
strict mode: required property "currency" is not defined at "#/$defs/presentation_validations/allOf/1/then" (strictRequired)
strict mode: missing type "object" for keyword "properties" at "#/$defs/presentation_validations/allOf/1/else" (strictTypes)
strict mode: missing type "object" for keyword "required" at "#/allOf/2/if/properties/presentation" (strictTypes)
strict mode: required property "description" is not defined at "#/allOf/2/if/properties/presentation" (strictRequired)
strict mode: required property "description" is not defined at "#/allOf/2/then" (strictRequired)
但是我不明白我需要更改,最重要的是,当我需要做它们时,就好像我要验证反对反对一些JSON,他们按预期工作。
这是codesandbox: https://codesandbox.io/s/ajv-strict-chtrict-box.io/ajv-strict-box-io/ajv-strict-box-io = Mode-Warnings-B88Re5
I have the following json schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Form Field configuration",
"properties": {
"title": {
"type": "string",
"title": "The field label"
},
"description": {
"type": "string",
"title": "The field description"
},
"presentation": {
"additionalProperties": false,
"type": "object",
"title": "Configuration for the field visual UI",
"properties": {
"inputType": {
"title": "The recommend way to represent the field visually.",
"anyOf": [
{
"const": "text",
"title": "Similar to the HTML `<input>` with text type."
},
{
"const": "number",
"title": "Similar to the HTML `<input>` with number type."
},
{
"const": "money",
"title": "Similar to 'number', dedicated to monetary values."
}
]
},
"currency": {
"title": "For inputType=money. Monetary Currency Code (3 digits)",
"maxLength": 3,
"minLength": 3,
"type": "string"
},
"description": {
"type": "string",
"title": "The field description with HTML"
}
}
},
"$template": {
"type": "string",
"title": "Pass the template URL to a given field"
}
},
"required": ["presentation"],
"allOf": [
{
"$comment": "Extend the base Draft-07 configuration",
"$ref": "http://json-schema.org/draft-07/schema#"
},
{
"$comment": "Add presentation validations only when $template is not present.",
"if": { "required": ["$template"] },
"else": {
"properties": {
"presentation": {
"$ref": "#/$defs/presentation_validations"
}
}
}
},
{
"if": {
"$comment": "If it contains presentation.description, then [root].description is also required.",
"properties": {
"presentation": {
"required": ["description"]
}
}
},
"then": {
"required": ["description"]
}
}
],
"$defs": {
"presentation_validations": {
"allOf": [
{
"required": ["inputType"]
},
{
"if": {
"properties": {
"inputType": { "const": "money" }
},
"required": ["inputType"]
},
"then": {
"required": ["currency"]
},
"else": {
"properties": { "currency": false }
}
}
]
}
}
}
If I log the strict mode warnings, I get the following warnings:
strict mode: required property "$template" is not defined at "#/allOf/1/if" (strictRequired)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/0" (strictTypes)
strict mode: required property "inputType" is not defined at "#/$defs/presentation_validations/allOf/0" (strictRequired)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/1/if" (strictTypes)
strict mode: missing type "object" for keyword "properties" at "#/$defs/presentation_validations/allOf/1/if" (strictTypes)
strict mode: missing type "object" for keyword "required" at "#/$defs/presentation_validations/allOf/1/then" (strictTypes)
strict mode: required property "currency" is not defined at "#/$defs/presentation_validations/allOf/1/then" (strictRequired)
strict mode: missing type "object" for keyword "properties" at "#/$defs/presentation_validations/allOf/1/else" (strictTypes)
strict mode: missing type "object" for keyword "required" at "#/allOf/2/if/properties/presentation" (strictTypes)
strict mode: required property "description" is not defined at "#/allOf/2/if/properties/presentation" (strictRequired)
strict mode: required property "description" is not defined at "#/allOf/2/then" (strictRequired)
But I don't understand what do I need to change and, most importantly, when I need to do them, as if I validate against some jsons, they work as expected.
Here's the codesandbox: https://codesandbox.io/s/ajv-strict-mode-warnings-b88re5
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
AJV的“严格模式”使您无法犯常见的错误,这可能会导致创建一个JSON模式,该模式的指定(或“明确指定”)比您预期的要少。
让我们考虑您看到的第一个错误。
必需
键>关键字仅适用于对象。这意味着,如果该位置的实例数据是另一种类型的字符串,则验证将通过。必需的
关键字并不意味着它必须是对象。如果您希望它是一个对象,则需要使用type
关键字来另外指定此类对象。AJV的严格模式规则“ stricttypes”明确要求您使用仅根据其类型应用的关键字,则指定类型。
考虑一个JSON模式,例如
{“必需”:“名称”}
。如果实例是一个对象,则需要“名称”。但是,如果实例数据为代码[]
,则在本示例中也将对给定的架构进行验证。AJV's "strict mode" prevents you from making common mistakes which could lead to creating a JSON Schema which is less specified (or "more underspecified") than you expect.
Let's take the first error you see.
The
required
keyword only applies to objects. This means if the instance data at that location was of another type, say, a string, then validation would pass. Therequired
keyword doesn't mean it has to be an object. If you want it to be an object, you need to additionally specify such using thetype
keyword.AJV's strict mode rule "strictTypes" explicitly requires that you specify the types if you use keywords which are only applied based on their type.
Consider a JSON Schema such as
{ "required": "name" }
. If the instance was an object, "name" would be required. However, if the instance data was in stead an array[]
, it would also pass validation for the given schema in this example.除了@ReleQuestual的答案。 jsonbuddy 中有一个内置的linter/Analyzer,它立即显示出一个主要问题:
在与其他关键字相同的架构上有一个
$ ref
。在2019 - 09年草案之前,在验证期间, 的所有关键字。AJV不抱怨您正在使用草稿7?这也存在于您的副本中吗?
通常,这样的错误解决方案是使用
allof
并将$ ref和所有其他定义包装在两个单独的(sub)架构中。喜欢:In addition to the answer of @relequestual. There is a built-in linter/analyzer in JSONBuddy and it shows a major issue in your schema immediately:
There is a
$ref
at the same schema as other keywords. Prior to draft 2019-09 all of the keywords next to$ref
at the same level are ignored during validation.AJV does not complain as you are using draft 7? Is this also present in your copy?
Often, a possible solution for an error like this is to use
allOf
and wrap the $ref and all other definitions in two separate (sub)schemas. Like: