【问题标题】:What is the correct use of json-schema used with ajv?与ajv一起使用的json-schema的正确用法是什么?
【发布时间】:2021-04-21 04:37:15
【问题描述】:

早上好, 在将 $ref 用于同一 json 文件中定义的内容时,我在使用带有 json 模式的 ajv 时遇到问题。我怀疑问题出在使用 id 上,我会对此了解更多。

我的文件是:

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": {
                "name":{"type":"string"},
                "surname":{"type":"string"},
                "email": {"type": "string", "format": "email"},
                "sex":{"$ref": "types.json#/definitions/gender"}},
            "required":["name", "surname", "sex", "email"]
        },
        "member":{
            "$schema":"http://json-schema.org/draft-06/schema#",
            "type": "object",
            "$id": "http://asite.org/schemas/member.json",
            "allOf":[
                {"$ref": "#/definitions/person"},
                {
                    "properties": {
                        "id":{"type":"integer"},
                        "role":{"$ref": "types.json#/properties/man_role"},
                        "is_expert":{"type":"boolean", "default":false},
                        "is_board":{"type":"boolean", "default": false}
                    }
                }
            ]
        }
    },
    "type":"object",
    "properties": {
        "person": {"$ref": "#/definitions/person"},
        "member": {"$ref": "#/definitions/member"}
    }
}

types.json

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

我查看了this 问题,但我没有弄清楚如何更正我的示例。 我得到的错误是:

MissingRefError: can't resolve reference #/definitions/person from id http://asite.org/schemas/member.json

如果我尝试使用 VisualStudio 代码,这些引用会起作用,例如,我可以创建一个“成员”,它还可以识别“人”的属性。

谁能告诉我应该如何编写这些模式以使它们与 ajv 一起使用?

产生错误的代码是:

import Ajv, {JSONSchemaType, DefinedError} from "ajv"
import {Person, Member} from "./definitions";
import addFormats from "ajv-formats"

const ajv = new Ajv();
addFormats(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 MemberSchema: JSONSchemaType<Member> = require('../definitions.json').definitions.member;
ajv.addSchema(types);

const isPerson = ajv.compile(PersonSchema);
const isMember = ajv.compile(MemberSchema)
//other stuff, use of isPerson and isMember on example objects

【问题讨论】:

    标签: json jsonschema ajv


    【解决方案1】:

    您的直觉是正确的,由于$id$ref 没有像您预期的那样解决。 $refs 针对架构的 $id 进行解析。在这种情况下,{ "$ref": "#/definitions/person" } 被解析为 "$id": "http://asite.org/schemas/member.json",导致 http://asite.org/schemas/member.json#/definitions/person 不存在。解决方案是使用人员架构的$id 而不是相对路径:{ "$ref": "person.json" }


    顺便说一句,您可能更喜欢用于编译模式的替代 API,这种 API 在处理像“definitions.json”这样的捆绑模式时效果更好。您可以加载整个文件,然后通过 $id 编译所需的各个架构。

    const ajv = new Ajv();
    ajv.addMetaSchema(draft06);
    ajv.addSchema(definitions);
    ajv.addSchema(types);
    const isPerson = ajv.getSchema("http://asite.org/schemas/person.json");
    const isMember = ajv.getSchema("http://asite.org/schemas/member.json");
    

    【讨论】:

    • 您好,谢谢您的回答。现在验证器工作了,但模式不再:使用 vscode 我看到它找不到“person.json”,因为它假定它是另一个文件。同样,当从 json-schema 生成 TypeScript 类型时,它不会因此而“编译”。验证器搜索对象的方式与架构的行为方式似乎不兼容
    • $id 是 JSON Schema 实现中最难做到的事情之一。 AJV 做对了(尽管我上次检查时它们也有突出的错误)。如果 vscode 在这方面有错误,我不会感到惊讶。您可能必须将每个架构放在它自己的文件中以避免该问题。
    猜你喜欢
    • 2018-11-25
    • 2018-04-10
    • 2013-01-02
    • 1970-01-01
    • 2020-08-27
    • 2020-07-10
    • 2020-09-29
    • 1970-01-01
    • 2012-05-12
    相关资源
    最近更新 更多