Поиск по сайту
Ctrl + K
Вопросы по Nest.js

Какова разница между перехватчиками и посредниками?

При работе с NestJS, многие начинающие разработчики могут сталкиваться с терминами "перехватчики" и "посредники" (middleware). Эти два концепта часто путают, однако они выполняют разные задачи в архитектуре приложения. Давайте разберёмся в их основных различиях и увидим примеры кода.

Определения

Промежуточное ПО (Middleware) — это функции, которые обрабатываются перед тем, как запрос достигнет маршрутизатора. Они могут использоваться для выполнения операций, таких как аутентификация, логирование, модификация объекта запроса и так далее. Middleware имеет доступ к объектам request, response и функции next, чтобы продолжить выполнение последовательности.

Перехватчики (Interceptors) — это функции, которые могут обрабатывать запросы и ответы во время обработки контроллером. Они обеспечивают более мощный способ для работы с результатами выполнения метода контроллера. Перехватчики могут трансформировать результат, модифицировать параметры запроса, а также реализовывать дополнительную логику перед возвращением ответа.

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

Давайте рассмотрим примеры кода для каждого из них.

Пример middleware

import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    console.log(`Request... Method: ${req.method} URL: ${req.url}`);
    next(); // Необходимо для перехода к следующему middleware или маршруту
  }
}

// Регистрация middleware в модуле
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  controllers: [AppController],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('*'); // Применить ко всем маршрутам
  }
}

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

Теперь давайте посмотрим на пример перехватчика.

Пример interceptor

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(`Response... ${Date.now() - now}ms`)),
      );
  }
}

// Регистрация interceptor в модуле
import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}

Заключение

  • Middleware обрабатывает запрос до того, как он достигнет контроллера. Его основная цель — выполнять общие задачи, такие как аутентификация и логирование.
  • Interceptors могут изменять данные как до, так и после того, как они были обработаны контроллером, и могут обрабатывать результат выполнения.
  • Оба инструмента полезны в различных ситуациях, и понимание их различий поможет вам лучше проектировать свои приложения на NestJS.