与 ajv 一起使用的 json-schema 的正确用法是什么?
What is the correct use of json-schema used with ajv?
早上好,
当对同一 json 文件中定义的内容使用 $ref 时,我在将 ajv 与 json-schema 一起使用时遇到问题。我怀疑问题出在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"}
}
}
我查看了 问题,但我没有弄清楚如何更正我的示例。
我得到的错误是:
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
您的直觉是正确的,由于 $id
,$ref
未按您预期的方式解析。 $ref
是根据架构的 $id
解析的。在这种情况下,{ "$ref": "#/definitions/person" }
针对 "$id": "http://asite.org/schemas/member.json"
进行解析,导致 http://asite.org/schemas/member.json#/definitions/person
不存在。解决方案是使用 person 模式的 $id
而不是相对路径:{ "$ref": "person.json" }
.
顺便说一句,您可能更喜欢替代 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");
早上好, 当对同一 json 文件中定义的内容使用 $ref 时,我在将 ajv 与 json-schema 一起使用时遇到问题。我怀疑问题出在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"}
}
}
我查看了
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
您的直觉是正确的,由于 $id
,$ref
未按您预期的方式解析。 $ref
是根据架构的 $id
解析的。在这种情况下,{ "$ref": "#/definitions/person" }
针对 "$id": "http://asite.org/schemas/member.json"
进行解析,导致 http://asite.org/schemas/member.json#/definitions/person
不存在。解决方案是使用 person 模式的 $id
而不是相对路径:{ "$ref": "person.json" }
.
顺便说一句,您可能更喜欢替代 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");