【发布时间】:2020-11-04 03:12:39
【问题描述】:
给定:
假设我正在为联系人定义一个架构。但是,我可以有“主要联系人”、“学生”或两者兼而有之;以及所有三种选择的不同属性。联系人类型在 contact_type: [ "Primary Contact", "Student" ] 数组中定义,可以是其中之一,也可以是两者。
假设每个联系人类型的字段都是这样的:
- 如果是主要联系人,那么我需要 phone_number
- 如果是学生,那么我想要名字
- 如果是学生和主要联系人,那么我需要 phone_number 和 first_name
用法
我使用Ajv 库在 Node.js 中使用如下代码进行验证:
function validator(json_schema){
const Ajv = require('ajv');
const ajv = new Ajv({allErrors: true});
return ajv.compile(json_schema)
}
const validate = validator(json_schema);
const valid = validate(input);
console.log(!!valid); //true or false
console.log(validate.errors)// object or null
注意:我在使用 anyOf 时遇到了allErrors: true 的问题,我使用allErrors 的输出将所有丢失/无效的字段返回给用户,而不是一次返回一个问题。参考:https://github.com/ajv-validator/ajv/issues/980
架构
我已经编写了以下架构,如果我执行“学生”或“主要联系人”,它就可以工作,但是当我通过两者时,它仍然想验证 ["Student"] 或 ["Primary Contact"] 而不是两者都有。
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [],
"properties": {},
"allOf": [
{
"if": {
"properties": {
"contact_type": {
"contains": {
"allOf": [
{
"type": "string",
"const": "Primary Contact"
},
{
"type": "string",
"const": "Student"
}
]
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"phone": {
"type": "string"
},
"first_name": {
"type": "string"
}
},
"required": [
"phone",
"first_name"
]
}
},
{
"if": {
"properties": {
"contact_type": {
"contains": {
"type": "string",
"const": "Student"
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"first_name": {
"type": "string"
}
},
"required": [
"first_name"
]
}
},
{
"if": {
"properties": {
"contact_type": {
"contains": {
"type": "string",
"const": "Primary Contact"
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"phone": {
"type": "string"
}
},
"required": [
"phone"
]
}
}
]
}
有效输入示例:
- 仅适用于 [“主要联系人”]:
{
"contact_type":["Primary Contact"],
"phone":"something"
}
- 仅适用于 ["Student"]:
{
"contact_type":["Student"],
"first_name":"something"
}
- 对于[“主要联系人”,“学生”]
{
"contact_type":["Primary Contact", "Student"],
"phone":"something",
"first_name":"something"
}
问题:
即使allErrors: true,我也想验证一下,这可能吗?如果没有,我应该如何更改架构?
脚注
除非万不得已,否则我不想将“contact_type”更改为数组。 (这是必须的,但只有在别无他法的情况下才能打破)
我不能允许任何附加项,因此我在 if 语句中完全定义了每个对象,尽管 contact_type 很常见。如果我将contact_type 移出,则会收到有关将contact_type 作为附加项传递的错误消息(它会查看if 语句的属性,并且在将其取出到公共位置时看不到contact_type)。这就是为什么我最初的 properties 对象是空的。
【问题讨论】:
-
这是完全可能的,我非常乐意提供帮助。乍一看,您至少犯了一个简单的错误,因为
contains没有使用模式对象。幸运的是,您可以通过稍微不同的方式实现您想要的。我正在为您制定解决方案 -
编辑:我错了包含...我需要 mroe coffee =D
标签: javascript node.js jsonschema json-schema-validator ajv