Валидация JSON Schema: данные, документация и подсказки кода
JSON Schema: Контракт данных
JSON Schema — это язык определения структур для данных JSON, подобно TypeScript для JavaScript, но применимый к валидации во время выполнения и межъязыковым сценариям.
| Назначение | Описание |
|---|---|
| Валидация данных | Проверка запросов/ответов API |
| Генерация документации | Автоматическая генерация документации API |
| Подсказки IDE | Интеллектуальное автодополнение в VS Code |
| Mock-данные | Автоматическая генерация тестовых данных |
| Валидация конфигурации | package.json, tsconfig.json и т. д. |
I. Базовые типы
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"email": { "type": "string", "format": "email" },
"isActive": { "type": "boolean" },
"score": { "type": "number", "minimum": 0, "maximum": 100 },
"tags": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
},
"required": ["name", "email"],
"additionalProperties": false
}
Встроенные форматы
| format | Правило соответствия | Пример |
|---|---|---|
email |
RFC 5322 | user@example.com |
uri |
URI | https://example.com |
date |
Дата ISO 8601 | 2026-06-02 |
time |
Время ISO 8601 | 14:30:00 |
date-time |
Дата и время ISO 8601 | 2026-06-02T14:30:00Z |
ipv4 |
Адрес IPv4 | 192.168.1.1 |
ipv6 |
Адрес IPv6 | ::1 |
uuid |
UUID | 550e8400-e29b-41d4-a716-446655440000 |
hostname |
Имя хоста | example.com |
II. Продвинутые паттерны
Вложенные объекты
{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"profile": {
"type": "object",
"properties": {
"avatar": { "type": "string", "format": "uri" },
"bio": { "type": "string", "maxLength": 200 }
}
}
}
}
}
}
Перечисления и объединённые типы
{
"status": {
"type": "string",
"enum": ["pending", "active", "completed", "cancelled"]
},
"id": {
"oneOf": [
{ "type": "string", "format": "uuid" },
{ "type": "integer", "minimum": 1 }
]
}
}
Условная валидация
{
"type": "object",
"properties": {
"paymentMethod": { "type": "string", "enum": ["credit_card", "bank_transfer"] },
"cardNumber": { "type": "string" },
"bankAccount": { "type": "string" }
},
"if": {
"properties": { "paymentMethod": { "const": "credit_card" } }
},
"then": {
"required": ["cardNumber"],
"properties": { "cardNumber": { "pattern": "^\\d{16}$" } }
},
"else": {
"required": ["bankAccount"]
}
}
Паттерны регулярных выражений
{
"phone": { "type": "string", "pattern": "^1[3-9]\\d{9}$" },
"postalCode": { "type": "string", "pattern": "^\\d{6}$" },
"slug": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
}
III. $ref и повторное использование определений
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zipCode": { "type": "string", "pattern": "^\\d{6}$" }
},
"required": ["street", "city", "zipCode"]
}
},
"type": "object",
"properties": {
"homeAddress": { "$ref": "#/$defs/address" },
"workAddress": { "$ref": "#/$defs/address" }
}
}
IV. Валидация во время выполнения
Ajv (самый быстрый валидатор)
import Ajv from 'ajv';
const ajv = new Ajv({ allErrors: true, strict: false });
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
},
required: ['name', 'age'],
};
const validate = ajv.compile(schema);
const valid = validate({ name: '张三', age: 25 });
if (!valid) {
console.log(validate.errors);
// [{ keyword: 'minimum', dataPath: '/age', message: 'must be >= 0' }]
}
Zod (TypeScript-первый подход)
import { z } from 'zod';
const UserSchema = z.object({
name: z.string().min(1).max(100),
age: z.number().int().min(0).max(150),
email: z.string().email(),
tags: z.array(z.string()).min(1).max(10),
});
// Автоматический вывод типов
type User = z.infer<typeof UserSchema>;
// Валидация
const result = UserSchema.safeParse(input);
if (result.success) {
console.log(result.data); // Типобезопасно
} else {
console.log(result.error.issues);
}
V. Интеллектуальные подсказки IDE
Конфигурация VS Code
// .vscode/settings.json
{
"json.schemas": [
{
"fileMatch": ["/config/*.json"],
"url": "./schemas/config-schema.json"
},
{
"fileMatch": ["package.json"],
"url": "https://json.schemastore.org/package"
}
]
}
Ссылка на Schema в JSON-файлах
{
"$schema": "./schemas/config-schema.json",
"name": "my-project"
// Автодополнение IDE, подсказки об ошибках
}
Schema Store
Schema Store предоставляет более 400 распространённых JSON Schema:
- package.json
- tsconfig.json
- .eslintrc.json
- docker-compose.json
- GitHub Actions workflows
VI. Генерация Schema из JSON
Использование инструментов
- Откройте Инструмент форматирования JSON
- Вставьте данные JSON
- Нажмите «Генерировать Schema»
- Автоматический вывод типов, перечислений и диапазонов
Инструменты командной строки
# Использовать json-schema-generator
npx json-schema-generator sample.json -o schema.json
# Использовать quicktype
npx quicktype sample.json -o schema.json --lang schema
VII. Генерация Mock-данных
import { faker } from '@faker-js/faker';
// Генерация Mock-данных на основе Schema
function generateMock(schema) {
if (schema.type === 'string') {
if (schema.format === 'email') return faker.internet.email();
if (schema.format === 'uri') return faker.internet.url();
if (schema.enum) return faker.helpers.arrayElement(schema.enum);
return faker.lorem.word();
}
if (schema.type === 'integer') return faker.number.int(schema);
if (schema.type === 'boolean') return faker.datatype.boolean();
if (schema.type === 'array') {
return Array.from({ length: 3 }, () => generateMock(schema.items));
}
if (schema.type === 'object') {
const result = {};
for (const [key, propSchema] of Object.entries(schema.properties)) {
result[key] = generateMock(propSchema);
}
return result;
}
}
VIII. Лучшие практики
- Всегда объявляйте
$schema: Указывайте версию Draft, чтобы избежать неоднозначности - Используйте
additionalProperties: false: Запрещайте неопределённые поля - Используйте
$defs+$ref: Переиспользуйте общие структуры - Используйте
formatвместо самостоятельного написания pattern: Более читаемо, валидатор обрабатывает автоматически - Интегрируйте валидацию в CI: Убедитесь, что ответы API всегда соответствуют Schema
- Управляйте версиями Schema: Синхронизируйте с версиями API, поддерживайте проверку обратной совместимости
#JSON Schema#数据校验#Ajv#Zod#API