Работа с массивами в Joi строится вокруг строгого описания структуры элементов и правил их расположения. Валидация массивов отличается от примитивных типов тем, что здесь важны не только значения, но и позиция элементов, их обязательность и допустимость пропусков.
items()
— базовое описание схемы элементов массиваМетод items() задаёт схему (или набор схем) для
элементов массива. Это основной инструмент, определяющий допустимые типы
значений внутри коллекции.
Когда передаётся одна схема, она применяется ко всем элементам массива:
import Joi from 'joi';
const schema = Joi.array().items(
Joi.string().min(3)
);
schema.validate(['abc', 'def', 'gh']);
В этом случае каждый элемент обязан быть строкой длиной не менее трёх символов.
Joi позволяет задавать несколько схем, формируя набор допустимых типов:
const schema = Joi.array().items(
Joi.string(),
Joi.number()
);
Массив может содержать строки и числа в любых позициях. Такой подход используется для слабоструктурированных данных.
Если требуется строгая типизация, используется комбинация
items() и дополнительных правил:
const schema = Joi.array()
.items(Joi.number().integer().positive())
.min(1)
.max(5);
Здесь массив допускает только положительные целые числа и ограничен по длине.
ordered()
— позиционная валидация элементовМетод ordered() задаёт строгую последовательность схем
для элементов массива. Каждый элемент соответствует конкретной
позиции.
const schema = Joi.array().ordered(
Joi.string(), // 0 индекс
Joi.number(), // 1 индекс
Joi.boolean() // 2 индекс
);
Пример валидного массива:
['user', 42, true]
Каждый элемент строго привязан к своей позиции. Лишние элементы недопустимы, если не предусмотрено дополнительное правило.
Если типы не совпадают с заданной последовательностью, валидация завершается ошибкой:
['user', true, 42] // ошибка: второй элемент должен быть number
Часто ordered() используется вместе с
.length():
const schema = Joi.array()
.ordered(
Joi.string(),
Joi.number()
)
.length(2);
Это усиливает гарантию фиксированной структуры данных.
sparse() —
разрешение «разреженных» массивовПо умолчанию Joi требует, чтобы все элементы массива были явно
определены. sparse() изменяет это поведение, разрешая
undefined в качестве допустимого значения.
const schema = Joi.array()
.items(Joi.string())
.sparse();
Теперь массив может содержать «пустоты»:
['a', undefined, 'c']
Без sparse() подобная структура вызовет ошибку
валидации.
undefinedВажно, что речь идёт именно о undefined, а не
null:
['a', null, 'c'] // null не становится допустимым автоматически
Если требуется разрешить null, это задаётся явно:
Joi.array().items(Joi.string().allow(null)).sparse();
Разреженные массивы часто встречаются при работе с индексированными данными, где позиции важнее плотности заполнения:
const schema = Joi.array()
.ordered(
Joi.string(),
Joi.string(),
Joi.string()
)
.sparse();
Допускается:
['a', undefined, 'c']
items, ordered и sparseЭти методы могут использоваться совместно, но их поведение имеет приоритеты.
items и
orderedconst schema = Joi.array()
.items(Joi.string())
.ordered(Joi.number(), Joi.boolean());
ordered() задаёт строгие позиции для первых
элементовitems() определяет правило для остальных элементовПример валидного массива:
[10, true, 'extra', 'values']
sparse в комбинированные схемыconst schema = Joi.array()
.items(Joi.string())
.ordered(Joi.number(), Joi.boolean())
.sparse();
Теперь допускаются пропуски:
[10, undefined, 'text']
ordered()
над items()Если элемент попадает под правило ordered(), оно имеет
приоритет над items():
Joi.array()
.items(Joi.string())
.ordered(Joi.number());
Первый элемент обязан быть числом, даже если items()
допускает строки.
ordered() фиксирует структуру по индексамitems() задаёт общий набор допустимых значенийsparse() управляет допустимостью
undefinedJoi.array().ordered(
Joi.string(),
Joi.number(),
Joi.boolean()
);
Используется для фиксированных протоколов обмена данными.
Joi.array().items(
Joi.string(),
Joi.number()
);
Подходит для неструктурированных данных.
Joi.array()
.ordered(
Joi.string(),
Joi.string(),
Joi.string()
)
.sparse();
Используется при работе с данными, где позиции важнее полноты заполнения.
items() приводит к ошибке
элементаordered() приводит к структурной
ошибке массиваundefined без sparse() считается
недопустимым значениемnull не становится допустимым автоматическиС точки зрения Joi массив можно представить как систему трёх уровней:
ordered) —
фиксирует позицииitems) — определяет
допустимые значенияsparse) —
регулирует полноту данныхТакое разделение позволяет точно описывать даже сложные формы данных, сохраняя предсказуемость валидации и контроль над структурой массива.