如何使用 Ajv 编译 JSON 架构的子集?
How can I compile a subset of a JSON Schema with Ajv?
我必须遵循 JSON 架构:
{
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
}
根据该架构,以下 object 有效:
{type: 'journal', title: 'foo'}
而这个不是:
{type: 'qux', title: ''}
有没有一种方法可以重用该架构的子集,以便我可以也单独验证类型和标题?
例如(在伪代码中)
const Ajv = require('ajv');
const ajv = new Ajv;
ajv.addSchema(/* see schema above */);
const validate_document = ajv.compile(/* see schema above */);
const validate_type = ajv.compile(/* reuse corresponding subset */);
const validate_title = ajv.compile(/* reuse corresponding subset */);
validate_document({type: 'qux', title: ''}); // false
validate_type('qux'); // false
validate_title(''); // false
我选择了这个解决方案,它允许我保留模式 "integrity"(我不需要将它分成更小的部分,这样它仍然易于阅读和理解)。
我需要做的就是在相关模式上设置 $id
键:
{
"$id": "document", <-- id for the whole schema
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"$id": "document-type", <-- id for the type schema
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"$id": "document-title", <-- id for the title schema
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
}
Ajv 允许您通过其在 Ajv#getSchema
中的 id 引用模式,它将模式编译为验证函数:
const validate_document = ajv.getSchema('document');
const validate_type = ajv.getSchema('document-type');
const validate_title = ajv.getSchema('document-title');
console.log(
'Is {type: "journal", title: "foo"} valid? '
, validate_document({type: "journal", title: "foo"})
); // true
console.log(
'Is "qux" a valid document type? '
, validate_type("qux")
); // false
console.log(
'Is "journal" a valid document type? '
, validate_type("journal")
); // true
console.log(
'Is "" a valid document title? '
, validate_title("")
); // false
console.log(
'Is "foo" a valid document title? '
, validate_title("foo")
); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.11.0/ajv.min.js"></script>
<script>
const ajv = new Ajv;
ajv.addSchema({
"$id": "document",
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"$id": "document-type",
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"$id": "document-title",
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
});
</script>
我必须遵循 JSON 架构:
{
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
}
根据该架构,以下 object 有效:
{type: 'journal', title: 'foo'}
而这个不是:
{type: 'qux', title: ''}
有没有一种方法可以重用该架构的子集,以便我可以也单独验证类型和标题?
例如(在伪代码中)
const Ajv = require('ajv');
const ajv = new Ajv;
ajv.addSchema(/* see schema above */);
const validate_document = ajv.compile(/* see schema above */);
const validate_type = ajv.compile(/* reuse corresponding subset */);
const validate_title = ajv.compile(/* reuse corresponding subset */);
validate_document({type: 'qux', title: ''}); // false
validate_type('qux'); // false
validate_title(''); // false
我选择了这个解决方案,它允许我保留模式 "integrity"(我不需要将它分成更小的部分,这样它仍然易于阅读和理解)。
我需要做的就是在相关模式上设置 $id
键:
{
"$id": "document", <-- id for the whole schema
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"$id": "document-type", <-- id for the type schema
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"$id": "document-title", <-- id for the title schema
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
}
Ajv 允许您通过其在 Ajv#getSchema
中的 id 引用模式,它将模式编译为验证函数:
const validate_document = ajv.getSchema('document');
const validate_type = ajv.getSchema('document-type');
const validate_title = ajv.getSchema('document-title');
console.log(
'Is {type: "journal", title: "foo"} valid? '
, validate_document({type: "journal", title: "foo"})
); // true
console.log(
'Is "qux" a valid document type? '
, validate_type("qux")
); // false
console.log(
'Is "journal" a valid document type? '
, validate_type("journal")
); // true
console.log(
'Is "" a valid document title? '
, validate_title("")
); // false
console.log(
'Is "foo" a valid document title? '
, validate_title("foo")
); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.11.0/ajv.min.js"></script>
<script>
const ajv = new Ajv;
ajv.addSchema({
"$id": "document",
"type": "object",
"required": [
"type",
"title"
],
"properties": {
"type": {
"$id": "document-type",
"enum": [
"journal",
"book",
"generic"
]
},
"title": {
"$id": "document-title",
"type": "string",
"minLength": 1,
"maxLength": 500
}
}
});
</script>