Схема Joi.array() используется для валидации массивов
произвольной структуры. Базовая проверка ограничивается только типом
значения:
import Joi from 'joi';
const schema = Joi.array();
schema.validate([1, 2, 3]); // корректно
schema.validate('not array'); // ошибка
При отсутствии уточнений допускаются любые элементы, включая смешанные типы.
Метод items() задаёт схему элементов массива. Это
основной механизм строгой типизации:
const schema = Joi.array().items(Joi.number());
schema.validate([1, 2, 3]); // корректно
schema.validate([1, '2', 3]); // ошибка
Допускается использование сложных схем:
const schema = Joi.array().items(
Joi.object({
id: Joi.number().required(),
name: Joi.string().required()
})
);
В этом случае каждый элемент массива должен соответствовать объектной схеме.
Для управления размером массива применяются методы
min(), max() и length():
const schema = Joi.array().min(2).max(5);
schema.validate([1]); // ошибка (меньше 2)
schema.validate([1, 2, 3, 4]); // корректно
schema.validate([1, 2, 3, 4, 5, 6]); // ошибка (больше 5)
Точное значение длины задаётся через length():
const schema = Joi.array().length(3);
schema.validate([1, 2, 3]); // корректно
schema.validate([1, 2]); // ошибка
Метод unique() запрещает повторяющиеся значения:
const schema = Joi.array().unique();
schema.validate([1, 2, 3]); // корректно
schema.validate([1, 1, 2]); // ошибка
Для сложных структур можно задать ключ сравнения:
const schema = Joi.array().unique('id');
schema.validate([
{ id: 1 },
{ id: 2 }
]); // корректно
При совпадении указанного поля элементы считаются дубликатами.
Поведение массива регулируется базовыми модификаторами:
const schema = Joi.array().required();
Запрещает undefined и null.
Пустой массив допускается по умолчанию, но может быть ограничен:
const schema = Joi.array().min(1);
Также можно запретить пустое значение явно:
const schema = Joi.array().empty();
При отсутствии items() массив может содержать любые
типы:
const schema = Joi.array();
schema.validate([1, 'text', true, null]);
При этом валидация ограничивается только самим фактом массива.
Метод contains() задаёт требование наличия хотя бы
одного элемента, соответствующего схеме:
const schema = Joi.array().items(Joi.number()).contains(5);
schema.validate([1, 2, 5]); // корректно
schema.validate([1, 2, 3]); // ошибка
Используется для проверки обязательного присутствия значения в коллекции.
Метод has() требует наличия хотя бы одного элемента,
удовлетворяющего схеме:
const schema = Joi.array().has(Joi.object({ role: 'admin' }));
schema.validate([
{ role: 'user' },
{ role: 'admin' }
]); // корректно
В отличие от contains(), логика ориентирована на
соответствие условию, а не конкретному значению.
ordered() задаёт фиксированную позиционную структуру
массива:
const schema = Joi.array().ordered(
Joi.string(),
Joi.number(),
Joi.boolean()
);
schema.validate(['text', 123, true]); // корректно
schema.validate([123, 'text', true]); // ошибка
Каждая позиция соответствует своей схеме.
items() — все элементы должны соответствовать набору
схем без привязки к позицииordered() — строгая позиционная структураПример комбинирования:
const schema = Joi.array().ordered(
Joi.string(),
Joi.number()
).items(Joi.any());
По умолчанию Joi допускает undefined в массиве.
Поведение можно контролировать через sparse():
const schema = Joi.array().sparse(false).items(Joi.number());
Теперь undefined в элементах запрещён:
schema.validate([1, undefined, 3]); // ошибка
Массивы могут быть рекурсивными:
const schema = Joi.array().items(
Joi.array().items(Joi.number())
);
schema.validate([[1, 2], [3, 4]]);
Поддерживается произвольная глубина вложенности при корректной схеме.
Частый сценарий — массив объектов с комплексной структурой:
const schema = Joi.array().items(
Joi.object({
id: Joi.number().required(),
tags: Joi.array().items(Joi.string())
})
);
Валидация распространяется на каждый уровень вложенности.
Метод custom() позволяет реализовать произвольные
проверки:
const schema = Joi.array().custom((value, helpers) => {
if (value.includes(0)) {
return helpers.error('array.containsZero');
}
return value;
});
Это применяется для бизнес-логики, которую невозможно выразить стандартными методами.
Joi позволяет выполнять трансформации через
custom():
const schema = Joi.array().custom((value) => {
return value.map(Number);
});
Также возможно нормализовать данные перед дальнейшей проверкой.
Сложные схемы часто включают несколько правил одновременно:
const schema = Joi.array()
.items(Joi.number())
.min(2)
.max(10)
.unique()
.required();
Такая композиция позволяет описывать строгие контракты для входных данных API и бизнес-логики.