首页 > 解决方案 > 如何将ajv与依赖的json-schemas一起使用?

问题描述

我正在尝试使 ajv 与两个 json 模式一起工作,一个依赖于另一个。这是我的模式的示例(简化):

类型.json

{
    "$schema":"http://json-schema.org/draft-04/schema#",
    "$id": "http://a.site.org/schemas/types.json",
    "type": "object",
    "definitions": {
        "gender":{"enum": ["male", "female"]}
    },
    "properties":{
        "gender":{"$ref": "#/definitions/gender"}
    }
}

定义.json

{
"$schema":"http://json-schema.org/draft-04/schema#",
"$id": "http://a.site.org/schemas/definitions.json",
"definitions": {
    "person":{
        "type":"object",
        "properties": {
            "username":{"type":"string"},
            "password": {"type":"string"},
            "name":{"type":"string"},
            "surname":{"type":"string"},
            "sex":{"$ref": "types.json#/properties/gender"},
            "email":{"type":"string", "format":"email"}
        },
        "required":["name", "surname", "sex", "email"]
    }
},
"type":"object",
"properties": {
    "person": {"$ref": "#/definitions/person"}
    }
}

从节点,我使用这样的ajv:

import Ajv, {JSONSchemaType, DefinedError} from "ajv"
import {Gender} from "./types"
import {Person} from "./definitions";
const ajv = new Ajv()

const types : JSONSchemaType<Gender>= require("../types.json");
const PersonSchema : JSONSchemaType<Person> = require('../definitions.json').definitions.person;

const isPerson = ajv.addSchema(types).compile(PersonSchema);
const riccardo:Person={name: "Riccardo", surname: "surname", sex: "male", email: "email@gmail.com"};
const personValid = isPerson(riccardo);
if (!personValid) console.log(isPerson.errors)

我得到的错误是:

错误:没有带有键或参考的模式“http://json-schema.org/draft-04/schema#”

更新: 如果我从 types.json 中删除“$schema ...”,我得到的错误是:

MissingRefError: can't resolve reference types.json#/definitions/gender from id #

我使用了这个参考:https ://github.com/ajv-validator/ajv/blob/master/docs/validation.md#modular-schemas

有谁知道我做错了什么?

标签: jsonjsonschemaajv

解决方案


根据以下答案的建议,问题出在草稿上。在这里,我发布了我是如何使用更新的 json-schema 草案解决的。

现在以这种方式更改文件:

类型.json

{
    "$schema":"http://json-schema.org/draft-06/schema#",
    "$id": "http://asite.org/schemas/types.json",
    "type": "object",
    "definitions": {
        "gender":{"enum": ["male", "female"]}
    },
    "properties":{
        "gender":{"$ref": "#/definitions/gender"}
    }
}

定义.json:

{
    "$id": "http://asite.org/schemas/definitions.json",
    "$schema":"http://json-schema.org/draft-06/schema#",
    "definitions": {
        "person":{
            "$schema":"http://json-schema.org/draft-06/schema#",
            "$id": "http://asite.org/schemas/person.json",
            "type":"object",
            "properties": {
                "username":{"type":"string"},
                "password": {"type":"string"},
                "name":{"type":"string"},
                "surname":{"type":"string"},
                "sex":{"$ref": "types.json#/definitions/gender"},
                "email":{"type":"string", "format":"email"}
            },
            "required":["name", "surname", "sex", "email"]
        }
    },
    "type":"object",
    "properties": {
        "person": {"$ref": "#/definitions/person"}
    }
}

以这种方式使用:

import Ajv, {JSONSchemaType, DefinedError} from "ajv"
import {Gender} from "./types"
import {Person} from "./definitions";
const ajv = new Ajv();
ajv.addMetaSchema(require("../node_modules/ajv/lib/refs/json-schema-draft-06.json"))

const types = require("../types.json");
const PersonSchema : JSONSchemaType<Person> = require('../definitions.json').definitions.person;
const isPerson = ajv.addSchema(types).compile(PersonSchema);
const riccardo:Person={name: "Riccardo", surname: "surname", sex: "male", email: "email@gmail.com"};

const personValid = isPerson(riccardo);
if (!personValid) console.log(isPerson.errors)

现在出现了不同的错误,但是删除它可以工作的“电子邮件”属性,所以这是另一回事:

错误:路径“#/properties/email”的架构中忽略了未知格式“email”


推荐阅读