Ответ
В NestJS запрос проходит через строго определенную цепочку (middleware -> guards -> interceptors -> pipes -> controller -> interceptors -> exception filters). Я настраивал эту цепочку для добавления логирования, авторизации и валидации.
Порядок выполнения:
- Глобальные и модульные Middleware: Идеально для логирования, CORS, сжатия данных. Они выполняются до маршрутизации.
- Guards: Проверяют права доступа на основе ролей или JWT-токена. Если guard возвращает
false, цепочка прерывается. - Interceptors (до обработчика): Могут трансформировать входящий запрос или добавлять дополнительную логику (например, логирование времени выполнения).
- Pipes: Преобразуют и валидируют данные для параметров обработчика (например, с помощью class-validator).
- Controller Handler: Выполняется целевой метод контроллера.
- Interceptors (после обработчика): Могут трансформировать исходящий ответ.
- Exception Filters: Перехватывают и обрабатывают исключения, возникшие на любом этапе.
Пример Guard и Pipe:
// Guard для проверки JWT
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization?.split(' ')[1];
if (!token) throw new UnauthorizedException();
try {
const payload = this.jwtService.verify(token);
request.user = payload; // Добавляем пользователя в запрос
return true;
} catch {
throw new UnauthorizedException('Неверный токен');
}
}
}
// Pipe для валидации DTO
@Injectable()
export class ValidationPipe implements PipeTransform {
async transform(value: any, metadata: ArgumentMetadata) {
const object = plainToClass(metadata.metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException('Валидация не пройдена');
}
return object;
}
}
Практическое применение: В моем последнем проекте я использовал глобальный interceptor для оборачивания всех ответов в единый формат { data: ..., timestamp: ... } и глобальный guard для проверки API-ключей на публичных эндпоинтах.