Skip to main content
Практика завдань

Що таке interceptors у NestJS?

Перехоплювачі в NestJS

Перехоплювачі обгортають виконання обробника маршруту і можуть:

  • Виконувати логіку до та/або після обробника
  • Трансформувати результат, повернутий обробником
  • Трансформувати винятки
  • Перекривати або розширювати базову поведінку обробника (наприклад, кешування)
  • Вимірювати час виконання

Вони реалізують інтерфейс NestInterceptor і використовують RxJS Observables.


Структура перехоплювача

typescript
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const now = Date.now(); return next .handle() // викликає обробник маршруту .pipe( tap(() => console.log(`Час виконання: ${Date.now() - now}ms`)) ); } }

Загальні шаблони перехоплювачів

1. Трансформація відповіді (обгортання в конверт)

typescript
import { map } from 'rxjs/operators'; @Injectable() export class TransformInterceptor<T> implements NestInterceptor<T, { data: T }> { intercept(context: ExecutionContext, next: CallHandler): Observable<{ data: T }> { return next.handle().pipe( map(data => ({ data, success: true, timestamp: new Date().toISOString() })) ); } } // Результат: { "data": {...}, "success": true, "timestamp": "..." }

2. Кешування

typescript
@Injectable() export class CacheInterceptor implements NestInterceptor { constructor(private cacheService: CacheService) {} async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> { const key = context.switchToHttp().getRequest().url; const cached = await this.cacheService.get(key); if (cached) return of(cached); // повернути з кешу, пропустити обробник return next.handle().pipe( tap(result => this.cacheService.set(key, result, 60)) ); } }

3. Вимірювання часу виконання

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

4. Мапінг винятків

typescript
import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; @Injectable() export class ErrorsInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( catchError(err => throwError(() => new BadGatewayException('Помилка зовнішнього сервісу')) ) ); } }

Застосування перехоплювачів

typescript
// На рівні методу @Get() @UseInterceptors(LoggingInterceptor) findAll() { ... } // На рівні контролера @Controller('users') @UseInterceptors(TransformInterceptor) export class UsersController {} // Глобально (в модулі, підтримує DI) @Module({ providers: [ { provide: APP_INTERCEPTOR, useClass: TransformInterceptor }, { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor }, ], })

Життєвий цикл запиту NestJS

Вхідний запит Проміжне ПЗ Охоронці (можуть відхиляти) Перехоплювачі (до) Труби (трансформація/перевірка) Обробник маршруту Перехоплювачі (після) Фільтри винятків (якщо помилка) Вихідна відповідь

Резюме

Перехоплювачі є потужними інструментами для перехресних питань — обгортання всіх відповідей в єдиний конверт, ведення журналу, кешування, вимірювання часу та мапінг помилок. Використовуйте оператори RxJS map, tap та catchError, щоб реагувати на виконання обробника та трансформувати результати.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань