我正在使用JSON模式进行数据建模。我定义了一个基本的Document
模式,以后可以用来定义模型模式(例如Product
,Category
,User
等)。
我这样做是因为我希望所有模型都继承某些结构/规则。例如,每个模型实例都应具有某些公共属性(例如id
,createdAt
,updatedAt
)。在OOP术语中:Product extends Document
,因此它继承其实例属性。在模式术语中(我认为),Document
是用于创建模型模式的元模式。
我已经定义了Document模式如下:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"id": "http://example.com/schemas/document.json#",
"title": "Document",
"type": "object",
"additionalProperties": false,
"required": ["type", "name", "fields"],
"properties": {
"type": {
"constant": "document"
},
"name": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"readOnly": {
"type": "boolean"
},
"properties": {
// common properties
// model-specific properties
}
}
}
$schema
,{{ 1}}等)?id
包含一些公共属性(properties
,id
,...),而不必在每个模型架构定义中都定义它们? 答案 0 :(得分:4)
JSON Schema不使用面向对象的范例,因此继承等概念无法很好地转换。 JSON模式是约束的集合。像大多数人习惯的那样,它是减性的而不是加性的。这意味着给定一个空模式, valid JSON文档的集合就是 all JSON文档的集合。添加关键字时,您将从有效的JSON文档集中减去。从集合中删除某些内容后,便无法将其重新添加。
因此,您可以使用合成来“扩展”模式,但是永远不能“覆盖”另一个模式定义的内容。
/ schema / base
{
"type": "object",
"properties": {
"foo": { "type": "string" }
"bar": { "type": "string" }
}
}
/ schema / extended
{
"allOf": [{ "$ref": "/schema/base" }],
"properties": {
"baz": { "type": "string" }
}
}
这里有一个简单的扩展名,非常适合JSON Schema。
/ schema / override
{
"allOf": [{ "$ref": "/schema/base" }],
"properties": {
"bar": { "type": "integer" },
"baz": { "type": "boolean" }
}
}
在此示例中,两个模式都有一个/properties/bar
字段。如果您从继承的角度考虑这一点,那么您会误解这里发生的事情。在这种情况下,两者“ / properties / bar”字段都必须有效。没有冲突可以解决。就像关键字所说,“所有”架构都必须有效。
希望能为您提供足够的信息来解决您的问题并避免最常见的陷阱。
答案 1 :(得分:1)
在使用NodeJ时,使用ajv验证器通过以下代码即可轻松解决简单模式的限制:
function extendJsonSchema(baseSchema, extendingSchema) {
let extendedSchema = Object.assign({}, extendingSchema);
extendedSchema.properties = Object.assign(extendedSchema.properties, baseSchema.properties)
extendedSchema.required = extendedSchema.required.concat(baseSchema.required)
return extendedSchema
}
let baseSchema = require('./base.schema.json')
let extendingSchema = require('./extending.schema.json')
let extendedSchema = extendJsonSchema(baseSchema, extendingSchema)
const validate = ajv.compile(extendedSchema)
这至少解决了我的用例。