DEV Community

azuli jerson
azuli jerson

Posted on

Interceptors nestjs

How do I use Interceptors in nestjs?

Top comments (2)

Collapse
 
kl_cage_a861d0e0fb04635ea profile image
Kl Cage

O que é um Interceptor em NestJS?

Em NestJS, um interceptor é uma classe que implementa a interface NestInterceptor e é usada para interceptar e transformar as requisições ou respostas de um controlador ou método. Interceptores são úteis para diversas tarefas, como manipulação de dados, tratamento de erros, logging, caching, entre outras.

Diferença entre um Interceptor Global e um Não Global

  • Interceptor Global: Aplicado a todas as rotas da aplicação. Configurado uma vez, ele automaticamente intercepta todas as requisições e respostas de todos os controladores e métodos.
  • Interceptor Não Global: Aplicado a um controlador específico ou a um método específico, permitindo um controle mais granular sobre onde o interceptor deve ser executado.

Criando e Implementando um Interceptor em NestJS

1. Criar o Interceptor

Arquivo: logging.interceptor.ts

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(`Execution time: ${Date.now() - now}ms`)),
      );
  }
}
Enter fullscreen mode Exit fullscreen mode

Explicação:

  • Este arquivo define um interceptor que loga o tempo de execução de cada requisição.
  • A classe LoggingInterceptor implementa a interface NestInterceptor.
  • O método intercept calcula o tempo de execução e loga essa informação.

2. Aplicar um Interceptor Não Global

Para aplicar o interceptor a um controlador ou método específico, usamos o decorator @UseInterceptors.

Arquivo: cats.controller.ts

  • Aplicar a um método específico:
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { LoggingInterceptor } from './logging.interceptor';

@Controller('cats')
export class CatsController {
  @Get()
  @UseInterceptors(LoggingInterceptor)
  findAll(): string {
    return 'This action returns all cats';
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Aplicar a um controlador inteiro:
import { Controller, UseInterceptors, Get } from '@nestjs/common';
import { LoggingInterceptor } from './logging.interceptor';

@Controller('cats')
@UseInterceptors(LoggingInterceptor)
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
Enter fullscreen mode Exit fullscreen mode

Explicação:

  • No primeiro exemplo, o LoggingInterceptor é aplicado apenas ao método findAll do CatsController.
  • No segundo exemplo, o LoggingInterceptor é aplicado a todos os métodos do CatsController.

3. Aplicar um Interceptor Global

Para aplicar um interceptor global, registramos o interceptor no módulo principal da aplicação.

Arquivo: app.module.ts

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { CatsController } from './cats.controller';
import { LoggingInterceptor } from './logging.interceptor';

@Module({
  imports: [],
  controllers: [CatsController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Explicação:

  • Registramos o LoggingInterceptor como um interceptor global no módulo principal da aplicação.
  • Usamos APP_INTERCEPTOR para indicar que o LoggingInterceptor deve ser aplicado globalmente.

Resumo das Etapas

  1. Criação do Interceptor (logging.interceptor.ts): Define a lógica do interceptor.
  2. Aplicação Não Global em um Método (cats.controller.ts): Usa @UseInterceptors no método específico.
  3. Aplicação Não Global em um Controlador (cats.controller.ts): Usa @UseInterceptors no controlador.
  4. Aplicação Global (app.module.ts): Registra o interceptor como global no módulo principal da aplicação.
Collapse
 
kl_cage_a861d0e0fb04635ea profile image
Kl Cage
  1. Crie o Middleware
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class ResponseTimeMiddleware implements NestMiddleware {
  private readonly logger = new Logger(ResponseTimeMiddleware.name);

  use(req: Request, res: Response, next: NextFunction): void {
    const start = Date.now();
    res.on('finish', () => {
      const duration = Date.now() - start;
      if (duration > 1000) {
        this.logger.warn(`Long Request: ${req.method} ${req.originalUrl} - ${duration}ms`);
      }
    });
    next();
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Configure o Middleware

Você precisa configurar o middleware em um módulo do seu aplicativo. Normalmente, isso é feito no módulo principal (AppModule).

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { ResponseTimeMiddleware } from './response-time.middleware';

@Module({
  // Outros imports e declarações do seu módulo
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(ResponseTimeMiddleware)
      .forRoutes('*'); // Isso aplica o middleware para todas as rotas
  }
}
Enter fullscreen mode Exit fullscreen mode