Привет, друг! Если ты читаешь эту статью, значит, хочешь научиться создавать строгие JSON-схемы, которые не только описывают структуру данных, но и проверяют их на соответствие строгим правилам. Мы поговорим о:
- Обязательных полях
- Перечислениях (enum)
- Регулярных выражениях (pattern)
- Условной логике (if, then, else)
И сделаем это с примерами, комментариями и немного юмора, чтобы было не только полезно, но и весело.
1. Обязательные поля (required)
Задача: У нас есть объект пользователя, и мы хотим убедиться, что в нём всегда присутствуют поля name и email.
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
🔍 Пояснение:
- "type": "object" — объект.
- "properties" — описание свойств объекта.
- "required" — список обязательных свойств.
✅ Пример валидных данных:
{ "name": "Alice", "email": "alice@example.com" }
❌ Пример невалидных данных:
{ "name": "Bob" }
2. Перечисления (enum)
Задача: У нас есть поле status, которое может принимать только значения "active", "inactive" или "pending".
{
"type": "object",
"properties": {
"status": { "type": "string", "enum": ["active", "inactive", "pending"] }
}
}
🔍 Пояснение:
- "enum" — ограничивает значение поля набором допустимых значений.
✅ Пример валидных данных:
{ "status": "active" }
❌ Пример невалидных данных:
{ "status": "archived" }
3. Регулярные выражения (pattern)
Задача: У нас есть поле phone, которое должно содержать номер телефона в формате +1234567890.
{
"type": "object",
"properties": {
"phone": { "type": "string", "pattern": "^\\+\\d{10}$" }
}
}
🔍 Пояснение:
- "pattern" — проверяет, соответствует ли строка заданному регулярному выражению.
✅ Пример валидных данных:
{ "phone": "+1234567890" }
❌ Пример невалидных данных:
{ "phone": "1234567890" }
4. Условная логика (if, then, else)
Задача: Если поле isStudent равно true, то поле age обязательно; если isStudent равно false, то поле grade обязательно.
{
"type": "object",
"properties": {
"isStudent": { "type": "boolean" },
"age": { "type": "integer" },
"grade": { "type": "string" }
},
"required": ["isStudent"],
"if": {
"properties": { "isStudent": { "const": true } }
},
"then": {
"required": ["age"]
},
"else": {
"required": ["grade"]
}
}
🔍 Пояснение:
- "if" — условие, проверяется, если оно истинно.
- "then" — применяется, если условие истинно.
- "else" — применяется, если условие ложно.
✅ Пример валидных данных:
{ "isStudent": true, "age": 20 }
{ "isStudent": false, "grade": "A" }
❌ Пример невалидных данных:
{ "isStudent": true, "grade": "A" }
5. Вложенные объекты и зависимости
Задача: У нас есть объект address, который содержит поле type. Если type равно "business", то поле department обязательно.
{
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["residential", "business"] },
"department": { "type": "string" }
},
"required": ["type"],
"if": {
"properties": { "type": { "const": "business" } }
},
"then": {
"required": ["department"]
}
}
}
}
🔍 Пояснение:
- Вложенные объекты описываются через "properties".
- Условная логика применяется внутри вложенных объектов.
✅ Пример валидных данных:
{ "address": { "type": "business", "department": "HR" } }
❌ Пример невалидных данных:
{ "address": { "type": "business" } }
6. Использование allOf, anyOf, oneOf
Задача: У нас есть объект, который должен соответствовать всем схемам из allOf, хотя бы одной из схем из anyOf или ровно одной из схем из oneOf.
{
"type": "object",
"allOf": [
{ "properties": { "name": { "type": "string" } } },
{ "properties": { "age": { "type": "integer" } } }
]
}
🔍 Пояснение:
- "allOf" — объект должен соответствовать всем схемам.
- "anyOf" — объект должен соответствовать хотя бы одной схеме.
- "oneOf" — объект должен соответствовать ровно одной схеме.
✅ Пример валидных данных:
{ "name": "Alice", "age": 30 }
❌ Пример невалидных данных:
{ "name": "Bob" }
7. Уникальные элементы в массиве (uniqueItems)
Задача: Убедиться, что массив tags не содержит повторяющихся значений.
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
}
},
"required": ["tags"]
}
🔍 Пояснение:
- "uniqueItems": true — гарантирует, что все значения в массиве уникальны.
✅ Пример валидных данных:
{ "tags": ["api", "json", "schema"] }
❌ Пример невалидных данных:
{ "tags": ["json", "json"] }
8. Валидация по длине строки (minLength, maxLength)
Задача: Поле password должно содержать от 8 до 20 символов.
{
"type": "object",
"properties": {
"password": {
"type": "string",
"minLength": 8,
"maxLength": 20
}
},
"required": ["password"]
}
🔍 Пояснение:
- minLength и maxLength — ограничивают количество символов в строке.
✅ Пример:
{ "password": "s3cr3t123" }
❌ Пример:
{ "password": "123" }
9. Зависимости между полями (dependencies / dependentRequired)
Задача: Если указано поле creditCard, то обязательно должно быть и billingAddress.
{
"type": "object",
"properties": {
"creditCard": { "type": "string" },
"billingAddress": { "type": "string" }
},
"dependentRequired": {
"creditCard": ["billingAddress"]
}
}
🔍 Пояснение:
- "dependentRequired" — если указано одно поле, другие становятся обязательными.
✅ Пример:
{ "creditCard": "4111111111111111", "billingAddress": "123 Main St" }
❌ Пример:
{ "creditCard": "4111111111111111" }
10. Комбинирование типов (type: [ ... ])
Задача: Поле id может быть как строкой, так и числом.
{
"type": "object",
"properties": {
"id": {
"type": ["string", "integer"]
}
},
"required": ["id"]
}
🔍 Пояснение:
- Указание массива типов означает, что поле может быть любым из указанных типов.
✅ Примеры:
{ "id": "abc123" }
{ "id": 123 }
❌ Пример невалидных данных:
{ "id": true }
🎁 Бонус: валидатор дат и времён
Задача: Проверка корректности ISO 8601 даты (YYYY-MM-DD) и времени (HH:MM:SS).
{
"type": "object",
"properties": {
"startDate": {
"type": "string",
"format": "date"
},
"startTime": {
"type": "string",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$"
}
},
"required": ["startDate", "startTime"]
}
🔍 Пояснение:
- "format": "date" — встроенный формат в JSON Schema (если поддерживается валидатором).
- "pattern" для времени — проверяет, что оно в формате HH:MM или HH:MM:SS.
✅ Пример:
{
"startDate": "2025-05-07",
"startTime": "14:30:00"
}
✨ Заключение
Ты только что научился:
✅ делать поля обязательными,
✅ использовать enum,
✅ применять регулярные выражения,
✅ настраивать условную логику,
✅ управлять зависимостями и вложенностью,
✅ и даже проверять типы, даты и уникальные массивы.
JSON Schema — это как скрупулёзный контролёр, который знает, что и где должно быть. Но ты теперь умеешь им управлять 💼😄