Interceptores

Intermedio
Nest
Nest
Actualizado: 15/06/2025

Interceptores

Los interceptores en NestJS son una característica fundamental que permite interceptar y transformar las peticiones HTTP antes de que lleguen a los controladores, así como las respuestas antes de que se envíen al cliente. Funcionan de manera similar a los middlewares, pero con capacidades más avanzadas y específicas para el contexto de autenticación y autorización.

Un interceptor implementa la interfaz NestInterceptor y utiliza el patrón de programación orientada a aspectos (AOP) para separar las preocupaciones transversales del código de negocio principal.

Creación de un interceptor básico

Para crear un interceptor, necesitas implementar la interfaz NestInterceptor y definir el método intercept. Este método recibe el contexto de ejecución y el siguiente manejador en la cadena:

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 request = context.switchToHttp().getRequest();
    const method = request.method;
    const url = request.url;
    
    console.log(`Petición entrante: ${method} ${url}`);
    
    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`Tiempo de respuesta: ${Date.now() - now}ms`))
      );
  }
}

El método intercept debe devolver un Observable que representa la respuesta del controlador. El parámetro next.handle() ejecuta el siguiente interceptor o el controlador final si no hay más interceptores en la cadena.

Interceptor para autenticación

En el contexto de autenticación, los interceptores son especialmente útiles para validar tokens, extraer información del usuario y añadir datos al contexto de la petición:

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UnauthorizedException } from '@nestjs/common';
import { Observable } from 'rxjs';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthInterceptor implements NestInterceptor {
  constructor(private jwtService: JwtService) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    
    if (!token) {
      throw new UnauthorizedException('Token no encontrado');
    }

    try {
      const payload = this.jwtService.verify(token);
      // Añadir información del usuario al request
      request.user = payload;
    } catch (error) {
      throw new UnauthorizedException('Token inválido');
    }

    return next.handle();
  }

  private extractTokenFromHeader(request: any): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

Este interceptor extrae el token JWT del header Authorization, lo valida y añade la información del usuario al objeto request para que esté disponible en los controladores.

Transformación de respuestas

Los interceptores también pueden transformar las respuestas antes de enviarlas al cliente. Esto es útil para estandarizar el formato de las respuestas o añadir metadatos:

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

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

Aplicación de interceptores

Los interceptores se pueden aplicar a diferentes niveles de la aplicación:

A nivel de controlador:

import { Controller, Get, UseInterceptors } from '@nestjs/common';

@Controller('users')
@UseInterceptors(AuthInterceptor)
export class UsersController {
  @Get()
  findAll() {
    return 'Lista de usuarios';
  }
}

A nivel de método específico:

@Controller('users')
export class UsersController {
  @Get()
  @UseInterceptors(LoggingInterceptor, ResponseInterceptor)
  findAll() {
    return 'Lista de usuarios';
  }
}

A nivel global en el módulo:

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

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

Interceptor con manejo de errores

Los interceptores pueden capturar y manejar errores que ocurren durante la ejecución de los controladores:

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

@Injectable()
export class ErrorInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      catchError(error => {
        console.error('Error capturado por interceptor:', error.message);
        
        if (error instanceof HttpException) {
          return throwError(() => error);
        }
        
        // Transformar errores no HTTP en respuestas estructuradas
        return throwError(() => new HttpException('Error interno del servidor', 500));
      })
    );
  }
}

Los interceptores proporcionan una forma elegante y reutilizable de implementar funcionalidades transversales como autenticación, logging, transformación de datos y manejo de errores, manteniendo el código de los controladores limpio y enfocado en la lógica de negocio específica.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Nest

Documentación oficial de Nest
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Nest es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Nest

Explora más contenido relacionado con Nest y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender qué son los interceptores en NestJS y su función principal.
  • Aprender a crear interceptores básicos implementando la interfaz NestInterceptor.
  • Utilizar interceptores para validar tokens JWT y gestionar autenticación.
  • Aplicar interceptores para transformar respuestas antes de enviarlas al cliente.
  • Implementar interceptores para capturar y manejar errores en la aplicación.