← Назад к вопросам

Что такое Interceptor в NestJS?

2.3 Middle🔥 131 комментариев
#Архитектура и паттерны#Фреймворки и библиотеки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Interceptor в NestJS

Interceptor — это мощный паттерн в NestJS, который позволяет перехватывать и трансформировать запросы и ответы.

Что такое Interceptor?

Interceptor — это класс, реализующий интерфейс NestInterceptor. Позволяет:

  • Трансформировать запрос перед попаданием в контроллер
  • Трансформировать ответ после обработки
  • Логировать, измерять время выполнения
  • Кэшировать результаты
  • Обрабатывать ошибки

Структура Interceptor

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    
    const start = Date.now();
    
    return next.handle().pipe(
      map(data => {
        const duration = Date.now() - start;
        console.log(`After... ${duration}ms`);
        return data;
      })
    );
  }
}

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

1. Логирование времени

@Injectable()
export class PerformanceInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const req = context.getRequest();
    const { method, url } = req;
    
    console.log(`[${method}] ${url} - Start`);
    const start = Date.now();
    
    return next.handle().pipe(
      tap({
        next: (data) => {
          const duration = Date.now() - start;
          console.log(`[${method}] ${url} - ${duration}ms`);
        }
      })
    );
  }
}

2. Трансформация ответа

@Injectable()
export class TransformResponseInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map(data => ({
        success: true,
        data: data,
        timestamp: new Date().toISOString(),
      }))
    );
  }
}

3. Кэширование результатов

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  private cache = new Map<string, any>();
  
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const req = context.getRequest();
    const key = `${req.method}:${req.url}`;
    
    if (req.method === 'GET' && this.cache.has(key)) {
      console.log(`Cache hit: ${key}`);
      return of(this.cache.get(key));
    }
    
    return next.handle().pipe(
      map(data => {
        if (req.method === 'GET') {
          this.cache.set(key, data);
        }
        return data;
      })
    );
  }
}

4. Обработка ошибок

@Injectable()
export class ErrorHandlingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      catchError(error => {
        console.error('Error occurred:', error);
        
        return throwError(() => ({
          statusCode: error.statusCode || 500,
          message: error.message || 'Internal Server Error',
          timestamp: new Date().toISOString(),
        }));
      })
    );
  }
}

Использование Interceptor

На уровне контроллера:

@Controller('users')
@UseInterceptors(LoggingInterceptor)
export class UsersController {
  @Get()
  findAll() {
    return [{ id: 1, name: 'John' }];
  }
}

На глобальном уровне:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalInterceptors(new LoggingInterceptor());
  await app.listen(3000);
}

Порядок выполнения (Pipeline)

Client Request
    ↓
Global Interceptors (Before)
    ↓
Controller Interceptors (Before)
    ↓
Guards
    ↓
Pipes
    ↓
Controller Handler
    ↓
Method Interceptors (After)
    ↓
Controller Interceptors (After)
    ↓
Global Interceptors (After)
    ↓
Exception Filters
    ↓
Response

Interceptor vs Middleware

АспектMiddlewareInterceptor
Доступ к контекстуНетДа
ОбластьГлобальноНа контроллер/метод
Трансформация ответаСложнееЛегко
Обработка ошибокНетДа
RxJSНетДа

Key takeaway

  • Interceptor = инструмент для cross-cutting concerns
  • Используют RxJS operators
  • Работают на уровне контроллеров
  • Идеальны для обработки ответов и мониторинга