我在我的node.js项目中使用AJV软件包。
我正在尝试根据几个模式文件验证一些数据。这两个架构文件都在同一目录中:
/dir
|
parent_schema.json
|
sub_schema.json
/data
|
data.json
我正在尝试获取$ref
属性正常工作的超简单示例,但是遇到了麻烦。 parent_schema.json
如下:
{
"properties": {
"foo": { "type": "string" },
"bar": { "$ref": "sub_schema.json" }
}
}
sub_schema.json
如下:
{
"properties": {
"sub1": { "type": "string" },
}
}
我正在尝试验证我的data.json
,为了完整起见,它看起来像:
{
"foo": "whatever",
"bar": {
"sub1": "sometext"
}
}
我遇到的问题是我的$ref
路径。我从AJV收到此错误:
MissingRefError {
message: "can't resolve reference subschema1.json from id #"
missingRef: "subschema1.json"
missingSchema: "subschema1.json"
}
有人知道我的路线出了什么问题吗?我知道您也应该使用#
来选择要匹配的特定属性,但是我希望使用整个模式。
答案 0 :(得分:1)
常见的误解是$ref
以某种方式“加载”文件。
看看ajv.js.org怎么说:
使用架构$ id作为基本URI将$ ref解析为uri引用(请参见示例)。
并且:
您不必将架构文件托管在用作架构$ id的URI上。这些URI仅用于标识模式,根据JSON Schema规范,验证器不应期望能够从这些URI下载模式。
例如,Ajv不会尝试从stack://over.flow/string
加载此架构:
{
"$id": "stack://over.flow/string",
"type": "string"
}
如果您要在其他模式中引用该模式,则它们都必须具有相同的基本URI stack://over.flow/
,例如
{
"$id": "stack://over.flow/object",
"type": "object",
"properties": {
"a": { "$ref": "string#" }
}
}
这里{ "$ref": "string#" }
说“在堆栈://over.flow/string处导入模式” ,所以您最终得到:
{
"$id": "stack://over.flow/object",
"type": "object",
"properties": {
"a": {
"$id": "stack://over.flow/string",
"type": "string"
}
}
}
这允许您组合小型架构:
const ajv = new Ajv;
ajv.addSchema({
"$id": "stack://over.flow/string",
"type": "string"
});
ajv.addSchema({
"$id": "stack://over.flow/number",
"type": "number"
});
const is_string = ajv.getSchema("stack://over.flow/string");
const is_number = ajv.getSchema("stack://over.flow/number");
console.log(is_string('aaa'), is_string(42));
console.log(is_number('aaa'), is_number(42));
const is_ab = ajv.compile({
"$id": "stack://over.flow/object",
"type": "object",
"properties": {
"a": { "$ref": "string#" },
"b": { "$ref": "number#" }
}
});
console.log(is_ab({a: "aaa", b: 42}));
console.log(is_ab({a: 42, b: "aaa"}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>
(请注意,在您的示例中,两个模式都不正确。在两个模式中都缺少{"type": "object"}
。)
回答您的问题:
const ajv = new Ajv;
ajv.addSchema({
"$id": "stack://over.flow/parent.schema",
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "$ref": "child.schema#" }
}
});
ajv.addSchema({
"$id": "stack://over.flow/child.schema",
"type": "object",
"properties": {
"sub1": { "type": "string" },
}
});
const is_parent = ajv.getSchema("stack://over.flow/parent.schema");
const is_child = ajv.getSchema("stack://over.flow/child.schema");
console.log(is_parent({
"foo": "whatever",
"bar": {
"sub1": "sometext"
}
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>