Как получить ссылку на тип из значения в схеме JSON
У меня есть схема JSON, и у меня есть 3 типа медиа, заголовок, изображение и аватар.
Каждый из этих типов медиа имеет различную структуру, поэтому я использую $ref
а также oneOf
указать, какие допустимые параметры.
Тем не менее, я не могу понять, как указать, какой ref использовать на основе значения родного брата.
Моя схема выглядит так
const mediaSchema = {
"type": "object",
"required": ["mediaType", "content", "points"],
"properties":{
"mediaType": {"type":"string", "pattern": "^(image|avatar|caption)$"},
"content": {
"oneOf": [
{"$ref":"#/definitions/image"},
{"$ref": "#/definitions/caption"},
{"$ref": "#/definitions/avatar"}
],
}
},
"definitions": {
"caption":
{"type": "object",
"required": ["text"],
"properties": {
"text": {"type": "string"},
"fontSize": {"type": "string", "pattern": "^[0-9]{1,3}px$"}
}
},
"image": {"type": "string", "format": "url"},
"avatar":
{"type": "object",
"properties": {
"name": {"type": "string"},
"image": {"type": "string", "format":"url"}
}
}
}
}
и когда я определяю аватар как
mediaItem = {
"mediaType":"avatar",
"content": {
"name": "user name",
"avatar": "https://urlToImage
}
}
это должно быть верно, но если я определю аватар как
mediaItem = {
"mediaType": "avatar",
"content": "https://urlToImage"
}
он должен выдать ошибку, так как это недопустимо для медиа типа аватара.
1 ответ
Вы на правильном пути, но вы должны поместить диспетчер oneOf в корень схемы и определить "content"
с 3-мя отдельными константами в качестве дискриминатора, например так:
{
"oneOf": [
{
"type": "object",
"properties": {
"mediaType": {
"const": "avatar"
},
"content": { "$ref": "#/definitions/avatar" }
},
"required": ["mediaType", "content"]
},
// ...
],
"definitions": {
// ...
}
}
Обратите внимание "const"
Ключевое слово существует только в последней версии схемы JSON (draft6). Может случиться, что используемая вами реализация валидатора пока не поддерживает его. В этом случае вы можете заменить "const": "avatar"
с одноэлементным перечислением типа "enum": ["avatar"]