JSON 架构 - 需要所有属性
JSON Schema - require all properties
JSON 架构中的 required
字段
JSON 架构具有 properties
、required
和 additionalProperties
字段。例如,
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
"required": [
"elephant",
"giraffe",
"polarBear"
],
"additionalProperties": false
}
将验证 JSON 个对象,例如:
{
"elephant": "Johnny",
"giraffe": "Jimmy",
"polarBear": "George"
}
但如果属性列表不完全 elephant, giraffe, polarBear
.
,将会失败
问题
我经常将 properties
的列表复制粘贴到 required
的列表中,当列表因拼写错误和其他愚蠢的错误而不匹配时,我会遇到烦人的错误。
是否有更短的方式来表示所有属性都是必需的,而不明确命名它们?
我怀疑是否存在指定所需属性的方法,而不是在所需数组中明确命名它们。
但是如果您经常遇到这个问题,我建议您编写一个小脚本来 post- 处理您的 json-schema 并自动为所有定义的对象添加所需的数组。
脚本只需要遍历json-schema树,在每一层,如果找到"properties"关键字,添加一个包含所有定义键的"required"关键字在同一级别的属性中。
让机器做钻孔工作。
您可以只使用 "minProperties" 属性 而不是显式命名所有字段。
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
"additionalProperties": false,
"minProperties": 3
}
我在单行代码中执行此操作,例如,如果我想在数据库中将 required
用于 insert
,但只想在执行update
.
prepareSchema(action) {
const actionSchema = R.clone(schema)
switch (action) {
case 'insert':
actionSchema.$id = `/${schema.$id}-Insert`
actionSchema.required = Object.keys(schema.properties)
return actionSchema
default:
return schema
}
}
按照其他人的建议,这里是这样的 post-处理 python 代码:
def schema_to_strict(schema):
if schema['type'] not in ['object', 'array']:
return schema
if schema['type'] == 'array':
schema['items'] = schema_to_strict(schema['items'])
return schema
for k, v in schema['properties'].items():
schema['properties'][k] = schema_to_strict(v)
schema['required'] = list(schema['properties'].keys())
schema['additionalProperties'] = False
return schema
如果您在 python 中使用库 jsonschema,请使用自定义验证器:
首先创建自定义验证器:
# Custom validator for requiring all properties listed in the instance to be in the 'required' list of the instance
def allRequired(validator, allRequired, instance, schema):
if not validator.is_type(instance, "object"):
return
if allRequired and "required" in instance:
# requiring all properties to 'required'
instanceRequired = instance["required"]
instanceProperties = list(instance["properties"].keys())
for property in instanceProperties:
if property not in instanceRequired:
yield ValidationError("%r should be required but only the following are required: %r" % (property, instanceRequired))
for property in instanceRequired:
if property not in instanceProperties:
yield ValidationError("%r should be in properties but only the following are properties: %r" % (property, instanceProperties))
然后扩展现有的验证器:
all_validators = dict(Draft4Validator.VALIDATORS)
all_validators['allRequired'] = allRequired
customValidator = jsonschema.validators.extend(
validator=Draft4Validator,
validators=all_validators
)
现在测试:
schema = {"allRequired": True}
instance = {"properties": {"name": {"type": "string"}}, "required": []}
v = customValidator(schema)
errors = validateInstance(v, instance)
你会得到错误:
'name' should be required but only the following are required: []
您可以使用以下功能:
export function addRequiredAttributeRecursive(schema) {
if (schema.type === 'object') {
schema.required = [];
Object.keys(schema.properties).forEach((key) => {
schema.required.push(key);
if (schema.properties[key].type === 'object') {
schema.properties[key] = addRequiredAttributeRecursive(
schema.properties[key],
);
} else if (schema.properties[key].type === 'array') {
schema.properties[key].items = addRequiredAttributeRecursive(
schema.properties[key].items,
);
}
});
} else if (schema.type === 'array') {
if (schema.items.type === 'object') {
schema.items = addRequiredAttributeRecursive(schema.items);
}
}
return schema;
}
它递归地为每个 属性 写入您拥有的架构中所有对象的 required
属性。
如果您使用Javascript,您可以使用property getter。
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
get required() { return Object.keys(this.properties) },
"additionalProperties": false
}
JSON 架构中的 required
字段
JSON 架构具有 properties
、required
和 additionalProperties
字段。例如,
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
"required": [
"elephant",
"giraffe",
"polarBear"
],
"additionalProperties": false
}
将验证 JSON 个对象,例如:
{
"elephant": "Johnny",
"giraffe": "Jimmy",
"polarBear": "George"
}
但如果属性列表不完全 elephant, giraffe, polarBear
.
问题
我经常将 properties
的列表复制粘贴到 required
的列表中,当列表因拼写错误和其他愚蠢的错误而不匹配时,我会遇到烦人的错误。
是否有更短的方式来表示所有属性都是必需的,而不明确命名它们?
我怀疑是否存在指定所需属性的方法,而不是在所需数组中明确命名它们。
但是如果您经常遇到这个问题,我建议您编写一个小脚本来 post- 处理您的 json-schema 并自动为所有定义的对象添加所需的数组。
脚本只需要遍历json-schema树,在每一层,如果找到"properties"关键字,添加一个包含所有定义键的"required"关键字在同一级别的属性中。
让机器做钻孔工作。
您可以只使用 "minProperties" 属性 而不是显式命名所有字段。
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
"additionalProperties": false,
"minProperties": 3
}
我在单行代码中执行此操作,例如,如果我想在数据库中将 required
用于 insert
,但只想在执行update
.
prepareSchema(action) {
const actionSchema = R.clone(schema)
switch (action) {
case 'insert':
actionSchema.$id = `/${schema.$id}-Insert`
actionSchema.required = Object.keys(schema.properties)
return actionSchema
default:
return schema
}
}
按照其他人的建议,这里是这样的 post-处理 python 代码:
def schema_to_strict(schema):
if schema['type'] not in ['object', 'array']:
return schema
if schema['type'] == 'array':
schema['items'] = schema_to_strict(schema['items'])
return schema
for k, v in schema['properties'].items():
schema['properties'][k] = schema_to_strict(v)
schema['required'] = list(schema['properties'].keys())
schema['additionalProperties'] = False
return schema
如果您在 python 中使用库 jsonschema,请使用自定义验证器:
首先创建自定义验证器:
# Custom validator for requiring all properties listed in the instance to be in the 'required' list of the instance
def allRequired(validator, allRequired, instance, schema):
if not validator.is_type(instance, "object"):
return
if allRequired and "required" in instance:
# requiring all properties to 'required'
instanceRequired = instance["required"]
instanceProperties = list(instance["properties"].keys())
for property in instanceProperties:
if property not in instanceRequired:
yield ValidationError("%r should be required but only the following are required: %r" % (property, instanceRequired))
for property in instanceRequired:
if property not in instanceProperties:
yield ValidationError("%r should be in properties but only the following are properties: %r" % (property, instanceProperties))
然后扩展现有的验证器:
all_validators = dict(Draft4Validator.VALIDATORS)
all_validators['allRequired'] = allRequired
customValidator = jsonschema.validators.extend(
validator=Draft4Validator,
validators=all_validators
)
现在测试:
schema = {"allRequired": True}
instance = {"properties": {"name": {"type": "string"}}, "required": []}
v = customValidator(schema)
errors = validateInstance(v, instance)
你会得到错误:
'name' should be required but only the following are required: []
您可以使用以下功能:
export function addRequiredAttributeRecursive(schema) {
if (schema.type === 'object') {
schema.required = [];
Object.keys(schema.properties).forEach((key) => {
schema.required.push(key);
if (schema.properties[key].type === 'object') {
schema.properties[key] = addRequiredAttributeRecursive(
schema.properties[key],
);
} else if (schema.properties[key].type === 'array') {
schema.properties[key].items = addRequiredAttributeRecursive(
schema.properties[key].items,
);
}
});
} else if (schema.type === 'array') {
if (schema.items.type === 'object') {
schema.items = addRequiredAttributeRecursive(schema.items);
}
}
return schema;
}
它递归地为每个 属性 写入您拥有的架构中所有对象的 required
属性。
如果您使用Javascript,您可以使用property getter。
{
"type": "object",
"properties": {
"elephant": {"type": "string"},
"giraffe": {"type": "string"},
"polarBear": {"type": "string"}
},
get required() { return Object.keys(this.properties) },
"additionalProperties": false
}