Библиотека Class-validator выполняет проверку
объектов по модели, которая изначально ориентирована на полноформатную
(eager) валидацию: при вызове validate() или
validateOrReject() анализируются все декорированные
свойства класса, формируется полный список ошибок без прерывания
процесса.
Такой подход обеспечивает максимальную полноту диагностики, но может быть избыточным в сценариях, где:
Ленивая валидация в контексте Class-validator — это набор практик и встроенных механизмов, позволяющих сократить количество выполняемых проверок, прекратить валидацию на раннем этапе или избегать ненужных вычислений для части полей.
Одним из базовых механизмов ленивого поведения является опция
stopAtFirstError.
import { validate } from "class-validator";
await validate(user, {
stopAtFirstError: true,
});
При включении данного режима:
Особенность заключается в том, что остановка происходит на уровне цепочки проверок, но не гарантирует мгновенный выход из всего процесса валидации при глубоко вложенных структурах.
validateIfМеханизм validateIf позволяет полностью исключить
выполнение валидаторов для свойства, если условие возвращает
false.
import { validateIf, IsEmail } from "class-validator";
class User {
isEmailRequired: boolean;
@validateIf(o => o.isEmailRequired)
@IsEmail()
email: string;
}
Логика работы:
false все последующие декораторы игнорируются,Этот механизм часто используется для:
Группы (groups) позволяют разделять наборы правил
валидации и выполнять только часть из них.
import { IsString, Length } from "class-validator";
class User {
@IsString({ groups: ["create"] })
@Length(10, 20, { groups: ["create"] })
password: string;
@IsString({ groups: ["update"] })
@Length(6, 20, { groups: ["update"] })
nickname: string;
}
Вызов:
validate(user, { groups: ["update"] });
Особенности ленивого поведения через группы:
Группы часто используются в системах, где один DTO обслуживает несколько сценариев использования.
Опция skipMissingProperties снижает объём проверок за
счёт исключения отсутствующих значений:
validate(user, {
skipMissingProperties: true,
});
Поведение:
undefined не проходят валидацию,Это особенно эффективно при:
Создание кастомных валидаторов позволяет реализовать более агрессивную ленивую стратегию внутри одного правила.
import {
ValidatorConstraint,
ValidatorConstraintInterface,
} from "class-validator";
@ValidatorConstraint({ name: "isEven", async: false })
class IsEvenConstraint implements ValidatorConstraintInterface {
validate(value: number) {
if (value == null) return true;
if (value % 2 !== 0) return false;
return true;
}
defaultMessage() {
return "Значение должно быть чётным";
}
}
Ленивые паттерны внутри validate:
В сложных системах кастомные валидаторы становятся основным инструментом оптимизации.
validateIf и вычисляемые зависимостиБолее сложные сценарии ленивой проверки строятся на зависимостях между полями:
class Payment {
method: string;
@validateIf(o => o.method === "card")
cardNumber: string;
@validateIf(o => o.method === "bank")
iban: string;
}
Такая модель:
При использовании связки с class-transformer ленивость
может усиливаться за счёт ограничения входных данных до минимально
необходимого набора:
import { plainToInstance } from "class-transformer";
import { validate } from "class-validator";
const dto = plainToInstance(User, payload, {
excludeExtraneousValues: true,
});
await validate(dto);
Эффект:
При работе с вложенными DTO ленивость достигается комбинацией:
validateNested,validateIf,class Address {
@IsString()
city: string;
}
class User {
@validateIf(o => o.includeAddress)
address: Address;
}
Особенности:
На практике ленивое поведение формируется не одним инструментом, а их сочетанием:
stopAtFirstError — ограничение глубины
диагностики,validateIf — исключение веток валидации,groups — сегментация сценариев,skipMissingProperties — игнорирование пустых
значений,Типовой оптимизированный сценарий:
await validate(user, {
groups: ["update"],
skipMissingProperties: true,
stopAtFirstError: true,
});
Такой подход уменьшает количество проверок до строго необходимого минимума, сохраняя корректность в рамках выбранного сценария выполнения.