Минимальное и максимальное количество элементов

В Joi работа с массивами строится вокруг строгого контроля их размера. Это включает ограничение минимального и максимального количества элементов, а также фиксацию точной длины. Подобные правила применяются через цепочку методов, которые задают структурные ограничения и позволяют формировать предсказуемые схемы данных.

Основной метод array()

Любая схема массива начинается с объявления типа:

import Joi from 'joi';

const schema = Joi.array();

На этом уровне массив допускает любое количество элементов, включая пустой.


Ограничение минимального количества элементов

Метод min() задаёт нижнюю границу длины массива. Он гарантирует, что массив содержит не меньше указанного числа элементов.

Базовый пример

const schema = Joi.array().min(2);

schema.validate([1, 2]);       // валидно
schema.validate([1]);          // ошибка
schema.validate([]);           // ошибка

Поведение валидации

  • если элементов меньше минимального значения — возникает ошибка
  • если элементов ровно или больше — проверка проходит

Использование с объектами

Часто массивы содержат структурированные данные:

const schema = Joi.array().min(1).items(
  Joi.object({
    id: Joi.number().required(),
    name: Joi.string().required()
  })
);

В этом случае ограничение min(1) гарантирует, что хотя бы один объект присутствует, независимо от его содержимого.


Сообщения об ошибках

Можно переопределить стандартное сообщение:

const schema = Joi.array()
  .min(3)
  .messages({
    'array.min': 'Массив должен содержать минимум 3 элемента'
  });

Ограничение максимального количества элементов

Метод max() задаёт верхний предел длины массива.

Пример использования

const schema = Joi.array().max(5);

schema.validate([1, 2, 3]);        // валидно
schema.validate([1, 2, 3, 4, 5]);  // валидно
schema.validate([1, 2, 3, 4, 5, 6]); // ошибка

Практическое применение

Ограничение максимума часто используется для:

  • списков тегов
  • набора фильтров
  • ограниченного числа вложений
  • UI-ограничений (например, выбор до 3 элементов)

Комбинация с другими правилами

const schema = Joi.array()
  .items(Joi.string())
  .max(10)
  .min(1);

Такая схема задаёт строгий диапазон допустимого размера массива.


Фиксированное количество элементов

Метод length() задаёт точное количество элементов в массиве.

const schema = Joi.array().length(3);

schema.validate([1, 2, 3]);    // валидно
schema.validate([1, 2]);       // ошибка
schema.validate([1, 2, 3, 4]); // ошибка

Использование в структурированных данных

Фиксированная длина полезна, когда массив имеет строго определённую структуру:

const schema = Joi.array().length(2).items(
  Joi.number()
);

schema.validate([10, 20]); // валидно

Взаимодействие min, max и length

При комбинировании этих методов действует логика пересечения ограничений:

const schema = Joi.array()
  .min(2)
  .max(5)
  .length(3);

В данном случае:

  • length(3) делает min и max фактически избыточными
  • итоговое требование: строго 3 элемента

Валидация пустых массивов

По умолчанию пустой массив допустим:

Joi.array().validate([]); // валидно

Ограничения:

Joi.array().min(1).validate([]); // ошибка

Пустые массивы часто рассматриваются как отсутствие данных, и контроль min(1) превращает их в запрещённое состояние.


Использование с allow() и required()

Ограничения длины можно сочетать с обязательностью поля:

const schema = Joi.object({
  tags: Joi.array().min(1).max(5).required()
});

Здесь:

  • поле обязательно
  • массив не может быть пустым
  • количество элементов ограничено диапазоном

Вложенные массивы и сложные структуры

const schema = Joi.array().min(1).max(3).items(
  Joi.array().min(2).max(4).items(Joi.number())
);

Такой подход задаёт:

  • внешний массив: 1–3 элемента
  • внутренние массивы: 2–4 числа

Поведение при преобразовании данных

Joi может выполнять неявные преобразования типов, но ограничения min/max применяются уже после приведения:

const schema = Joi.array().min(2);

schema.validate('a,b'); 

Если включено преобразование, строка может быть преобразована в массив, после чего проверяется длина.


Строгая валидация и stripUnknown

При работе с массивами объектов ограничения длины часто комбинируются с очисткой данных:

const schema = Joi.array()
  .min(1)
  .max(10)
  .items(
    Joi.object({
      id: Joi.number().required()
    }).unknown(false)
  );

Это позволяет одновременно контролировать:

  • количество элементов
  • структуру каждого элемента
  • отсутствие лишних полей

Ошибки и коды валидации

Типичные коды ошибок:

  • array.min — недостаточно элементов
  • array.max — превышено количество элементов
  • array.length — несоответствие фиксированной длине

Каждый из них может быть переопределён через messages() для стандартизации ответов API.


Детерминированные схемы данных

Использование min, max и length формирует детерминированную структуру входных данных, где:

  • исключается неопределённость размера
  • упрощается обработка на уровне бизнес-логики
  • повышается предсказуемость API

Такая модель особенно важна при работе с формами, фильтрами и ограниченными наборами данных.