Привет! Ты когда-нибудь сталкивался с ситуацией, когда получаешь JSON-объект, а он не соответствует твоим ожиданиям? Например, в нём нет обязательного поля, тип данных не тот или значение выходит за пределы допустимого диапазона. Знакомо? Тогда тебе точно стоит познакомиться с JSON Schema — инструментом, который помогает описывать структуру данных и проверять их корректность.
Что такое JSON Schema?
JSON Schema — это спецификация, описывающая структуру JSON-данных. С помощью неё можно:
- Убедиться, что данные соответствуют ожидаемой структуре.
- Проверить типы данных.
- Задать обязательные поля.
- Ограничить значения (например, возраст должен быть больше 18).
Пример использования JSON Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 18 }
},
"required": ["name", "age"]
}
Этот пример описывает объект с двумя свойствами: name (строка) и age (целое число, не менее 18). Оба поля обязательны.
Основные типы данных в JSON Schema
JSON Schema поддерживает следующие типы данных:
- string — строка.
- number — число (включает как целые, так и вещественные числа).
- integer — целое число.
- boolean — логическое значение (true или false).
- null — значение null.
- object — объект (набор пар "ключ-значение").
- array — массив.
Пример схемы для пользователя:
{
"type": "object",
"properties": {
"username": { "type": "string" },
"isActive": { "type": "boolean" }
}
}
Структура JSON Schema
Типичная структура JSON Schema включает:
- $schema: указывает версию спецификации.
- $id: уникальный идентификатор схемы.
- title: название схемы.
- description: описание схемы.
- type: тип данных (например, object).
- properties: описание свойств объекта.
- required: список обязательных свойств.
Пример:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"description": "A user in the system",
"type": "object",
"properties": {
"username": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["username", "email"]
}
Примеры задач с разбором
1. Валидация простого объекта
Схема:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 18 }
},
"required": ["name", "age"]
}
Данные:
{ "name": "Alice", "age": 25 }
Результат: ✅ Данные валидны.
2. Проверка формата email
Схема:
{
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" }
},
"required": ["email"]
}
Данные:
{ "email": "user@example.com" }
Результат: ✅ Данные валидны.
3. Ограничение на минимальный возраст
Схема:
{
"type": "object",
"properties": {
"age": { "type": "integer", "minimum": 18 }
},
"required": ["age"]
}
Данные:
{ "age": 16 }
Результат: ❌ Данные невалидны (возраст меньше 18).
4. Перечисление допустимых значений (enum)
Схема:
{
"type": "object",
"properties": {
"status": { "type": "string", "enum": ["active", "inactive", "pending"] }
},
"required": ["status"]
}
Данные:
{ "status": "active" }
Результат: ✅ Данные валидны.
5. Валидация массива
Схема:
{
"type": "array",
"items": { "type": "string" },
"minItems": 2
}
Данные:
["apple", "banana"]
Результат: ✅ Данные валидны.
6. Вложенные объекты
Схема:
{
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
},
"required": ["street", "city"]
}
},
"required": ["address"]
}
Данные:
{ "address": { "street": "Main St", "city": "Somewhere" } }
Результат: ✅ Данные валидны.
7. Условная валидация (if/then/else)
Схема:
{
"type": "object",
"properties": {
"age": { "type": "integer" }
},
"if": {
"properties": { "age": { "type": "integer", "minimum": 18 } }
},
"then": {
"properties": { "age": { "maximum": 100 } }
},
"else": {
"properties": { "age": { "maximum": 17 } }
}
}
Данные:
{ "age": 20 }
Результат: ✅ Данные валидны.
Конечно! Давай ещё раз разберём использование регулярных выражений (RegExp) в JSON Schema — наглядно, живо и с комментариями.
🔍 Пример 8: Использование регулярных выражений
Регулярные выражения (pattern) в JSON Schema помогают проверять, соответствует ли строка определённому шаблону.
🎯 Задача:
Проверить, что строка является корректным номером автомобиля в формате "A123BC" (одна латинская буква, три цифры, две латинские буквы).
🧠 Схема с RegExp:
{
"type": "object",
"properties": {
"carNumber": {
"type": "string",
"pattern": "^[A-Z]{1}[0-9]{3}[A-Z]{2}$"
}
},
"required": ["carNumber"]
}
💬 Пояснение:
- "^" — начало строки.
- "[A-Z]{1}" — одна заглавная латинская буква.
- "[0-9]{3}" — три цифры.
- "[A-Z]{2}" — две заглавные латинские буквы.
- "$" — конец строки.
💡 Важно: JSON Schema использует JavaScript-совместимый синтаксис RegExp. Экрапировать \ нужно двойным \\, если вы пишете внутри JSON-строки.
✅ Пример валидных данных:
{ "carNumber": "A123BC" }
🟢 Всё отлично — соответствует шаблону.
❌ Примеры невалидных данных:
{ "carNumber": "AB123C" }
🔴 Не соответствует: порядок символов не такой.
{ "carNumber": "A123B" }
🔴 Не соответствует: не хватает одной буквы в конце.
{ "carNumber": "a123bc" }
🔴 Не соответствует: буквы не заглавные (нужны A-Z, а не a-z).
📦 Бонус: RegExp для валидации других форматов
📚 Вывод
Регулярные выражения в JSON Schema — мощный инструмент для точной валидации строковых значений. Главное — не забывать, что:
- pattern работает только с типом string.
- Он применяет JavaScript RegExp-синтаксис.
- Экрапирование — боль, но нужная боль (\\ вместо \ в JSON).
9. Валидация уникальных элементов массива
Схема:
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
}
},
"required": ["tags"]
}
💬 Что это делает:
Гарантирует, что в массиве tags все элементы уникальны.
Данные:
{ "tags": ["news", "tech", "news"] }
❌ Результат: данные невалидны — дубликат "news".
10. Использование allOf, anyOf, oneOf
allOf — все условия должны быть выполнены.
anyOf — достаточно хотя бы одного.
oneOf — должно выполняться ровно одно.
Пример с oneOf:
{
"type": "object",
"properties": {
"identifier": {
"oneOf": [
{ "type": "string", "pattern": "^user_[a-z]+$" },
{ "type": "integer", "minimum": 1 }
]
}
},
"required": ["identifier"]
}
💬 Что это делает:
identifier может быть либо строкой, начинающейся с "user_", либо положительным числом — но не обоими сразу.
Данные:
{ "identifier": 42 }
✅ Валидно.
{ "identifier": "user_alice" }
✅ Тоже валидно.
{ "identifier": "user_alice", "identifier": 1 }
❌ Невалидно — два условия сразу.
🎓 Где и как применять JSON Schema?
Вот реальные кейсы:
- 🔧 Валидация API запросов/ответов (в OpenAPI/Swagger).
- 🧪 Проверка JSON-конфигов в CI/CD.
- 🎮 Валидация игровых настроек (например, JSON-файлов от модов).
- 📄 Проверка пользовательских шаблонов (например, резюме в JSON).
- 🧾 Проверка данных из форм до отправки на сервер.
- 💬 Валидация WebSocket сообщений (особенно, если там JSON).
- 🛡 Безопасность: защита от "грязных" данных.
- 🔍 Линтинг и автодополнение в редакторах кода.
- 📦 Обеспечение совместимости между микросервисами.
🔧 Как валидировать JSON?
Есть множество валидаторов. Вот примеры:
- Node.js (Ajv):npm install ajv
const Ajv = require("ajv");
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data); - Python (jsonschema):pip install jsonschema
from jsonschema import validate
validate(instance=data, schema=schema)
🧠 Заключение
JSON Schema — это как строгий, но справедливый учитель: сначала кажется сложным, но потом ты начинаешь ценить порядок. Он:
✅ Упрощает разработку.
✅ Помогает ловить ошибки раньше.
✅ Отлично документирует структуру данных.
Что дальше?
- Попробуй написать свою первую схему.
- Добавь валидацию на сервер.
- Валидацию в CI/CD пайплайн.
- И наконец — расслабься, ты теперь знаешь больше, чем большинство разработчиков про JSON Schema 😄