Параметр strictGroups

В библиотеке class-validator механизм групп валидации используется для управления тем, какие правила применяются в разных сценариях работы с одной и той же моделью данных. Группы позволяют разделять бизнес-логики валидации, например: создание сущности, обновление, частичная проверка, административные операции.

Параметр strictGroups напрямую влияет на то, как библиотека обрабатывает указанные группы и насколько строго она следует им при выполнении валидации.


Общая роль групп валидации

Каждый валидатор в class-validator может быть привязан к одной или нескольким группам:

  • @IsString({ groups: ['create'] })
  • @IsOptional({ groups: ['update'] })

При вызове validate() можно указать, какие группы должны быть активны:

validate(user, { groups: ['create'] });

В этом случае будут применены только те правила, которые принадлежат группе create.


Поведение без strictGroups

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

  • если у валидатора не указаны группы, он считается универсальным
  • такие валидаторы выполняются всегда, независимо от переданных групп

Пример:

class User {
  @IsString()
  name: string;

  @IsEmail({ groups: ['create'] })
  email: string;
}

Валидация:

validate(user, { groups: ['create'] });

Результат:

  • name проверяется всегда
  • email проверяется только в группе create

Таким образом, отсутствие групп у декоратора делает его глобальным.


Включение strictGroups

Параметр strictGroups активируется при вызове validate:

validate(user, {
  groups: ['create'],
  strictGroups: true,
});

Он изменяет правило интерпретации групп:

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


Основное изменение поведения

При strictGroups: true:

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

Сравнение поведения

Без strictGroups

class Product {
  @IsString()
  title: string;

  @IsNumber({ groups: ['create'] })
  price: number;
}
validate(product, { groups: ['create'] });

Результат:

  • title проверяется всегда
  • price проверяется только в create

Со strictGroups

validate(product, {
  groups: ['create'],
  strictGroups: true,
});

Результат:

  • title НЕ проверяется
  • price проверяется

Практическое значение strictGroups

Использование strictGroups меняет философию валидации с «глобальной модели с исключениями» на «строго изолированные сценарии».

Это особенно важно в системах, где:

  • разные API используют одну и ту же модель
  • требуется строгая сегрегация логики создания и обновления
  • недопустимо случайное применение лишних правил

Типичные сценарии применения

Разделение Create и Update DTO

class UserDto {
  @IsString({ groups: ['create', 'update'] })
  username: string;

  @IsEmail({ groups: ['create'] })
  email: string;

  @IsOptional({ groups: ['update'] })
  password: string;
}

При strictGroups: true:

  • создание требует только явно указанных правил create
  • обновление использует только update

Изоляция административных проверок

class Account {
  @IsString()
  name: string;

  @IsBoolean({ groups: ['admin'] })
  isBlocked: boolean;
}
validate(account, {
  groups: ['admin'],
  strictGroups: true,
});

В этом режиме пользовательские проверки не применяются, если они не входят в admin.


Влияние на архитектуру DTO

Использование strictGroups требует более дисциплинированного подхода к моделям:

  • каждый валидатор должен быть явно отнесён к группе
  • отсутствующие группы становятся «неактивными зонами»
  • универсальные валидаторы перестают существовать

Это приводит к более явному контракту данных.


Частые ошибки при использовании

Отсутствие групп у декораторов

@IsString()
name: string;

При strictGroups: true это поле никогда не будет валидироваться, если не указаны группы.


Неполное покрытие группами

@IsEmail({ groups: ['create'] })
email: string;

При валидации update поле перестаёт проверяться полностью, если не добавлена соответствующая группа.


Логическая рассинхронизация

Когда разные разработчики добавляют декораторы без согласования групп, поведение модели становится непредсказуемым при включённом strictGroups.


Взаимодействие с другими опциями

always

Декоратор может быть помечен как:

@IsString({ always: true })

Но при включённом strictGroups приоритет имеет группа, и always не гарантирует выполнение, если нет пересечения с активной группой.


skipMissingProperties

В комбинации:

validate(dto, {
  groups: ['update'],
  strictGroups: true,
  skipMissingProperties: true,
});
  • строгая фильтрация валидаторов
  • пропуск отсутствующих полей
  • поведение становится максимально изолированным

Поведение при пустом groups

Если:

validate(user, {
  groups: [],
  strictGroups: true,
});

Результат:

  • валидируются только декораторы без групп
  • но при strictGroups такие декораторы также игнорируются
  • итоговая валидация может оказаться полностью пустой

Архитектурное значение strictGroups

strictGroups переводит систему валидации в режим:

  • явного контракта
  • строгого соответствия сценариям использования
  • отсутствия неявных правил

Это делает поведение более предсказуемым в больших приложениях, где одна DTO используется в нескольких контекстах.


Сравнение стратегий проектирования

Мягкая стратегия (без strictGroups)

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

Строгая стратегия (strictGroups)

  • только явные правила участвуют
  • всё поведение декларируется через группы
  • исключается неявная логика

Итоговое поведенческое правило

При включённом strictGroups:

  • участвуют только валидаторы, явно привязанные к переданным группам
  • декораторы без групп игнорируются
  • groups становится фильтром строгого включения, а не расширения логики