Как получить ссылку на тип из значения в схеме 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"]

Другие вопросы по тегам