Cómo implementar un módulo en NestJS que evite los Interceptores, Filtros y Guardias globales

  • 584Palabras
  • 3Minutos
  • 19 Jul, 2024

Al desarrollar aplicaciones NestJS, a veces necesitamos que ciertos módulos (como SpecialModule) eviten los interceptores globales (useGlobalInterceptors), filtros (useGlobalFilters) y guardias (useGlobalGuards). Este artículo explicará cómo implementar un módulo especial en NestJS, añadiendo lógica manualmente en los interceptores, filtros y guardias globales para omitir las rutas de SpecialModule.

Paso 1: Crear SpecialModule

Primero, creamos un SpecialModule. Puedes usar Nest CLI o crear el archivo del módulo manualmente.

Terminal window
1
nest g module special

Paso 2: Crear SpecialController y SpecialService

A continuación, creamos el controlador y el servicio para SpecialModule.

Terminal window
1
nest g controller special
2
nest g service special

En special.controller.ts añadimos una ruta simple:

1
import { Controller, Get } from "@nestjs/common";
2
import { SpecialService } from "./special.service";
3
4
@Controller("special")
5
export class SpecialController {
6
constructor(private readonly specialService: SpecialService) {}
7
8
@Get()
9
getSpecialData() {
10
return this.specialService.getSpecialData();
11
}
12
}

En special.service.ts añadimos un método simple:

1
import { Injectable } from "@nestjs/common";
2
3
@Injectable()
4
export class SpecialService {
5
getSpecialData() {
6
return { message: "Special data" };
7
}
8
}

Paso 3: Modificar AppModule para incluir SpecialModule

Asegúrate de que AppModule incluya SpecialModule:

1
import { Module } from "@nestjs/common";
2
import { SpecialModule } from "./special/special.module";
3
4
@Module({
5
imports: [SpecialModule],
6
controllers: [],
7
providers: [],
8
})
9
export class AppModule {}

Paso 4: Crear Interceptores, Filtros y Guardias globales

Crear interceptores, filtros y guardias globales, añadiendo lógica para omitir las rutas de SpecialModule.

Crear Interceptor global

1
import {
2
Injectable,
3
NestInterceptor,
4
ExecutionContext,
5
CallHandler,
6
} from "@nestjs/common";
7
import { Observable } from "rxjs";
8
import { tap } from "rxjs/operators";
9
10
@Injectable()
11
export class GlobalInterceptor implements NestInterceptor {
12
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
13
const controller = context.getClass();
14
const controllerName = controller.name;
15
16
// Verificar si pertenece al controlador SpecialController
17
if (controllerName === "SpecialController") {
18
return next.handle();
19
}
20
21
// Ejecutar la lógica del interceptor global
22
return next
23
.handle()
24
.pipe
25
// ... Añadir tu lógica global aquí
26
();
27
}
28
}

Crear Filtro global

1
import {
2
ExceptionFilter,
3
Catch,
4
ArgumentsHost,
5
HttpException,
6
} from "@nestjs/common";
7
import { Request, Response } from "express";
8
9
@Catch(HttpException)
10
export class GlobalFilter implements ExceptionFilter {
11
catch(exception: HttpException, host: ArgumentsHost) {
12
const ctx = host.switchToHttp();
13
const request = ctx.getRequest<Request>();
14
const response = ctx.getResponse<Response>();
15
const status = exception.getStatus();
16
17
const controller = host.getArgByIndex(1).constructor.name;
18
19
// Verificar si pertenece al controlador SpecialController
20
if (controller === "SpecialController") {
21
return response.status(exception.getStatus()).json({
22
statusCode: status,
23
message: exception.message,
24
});
25
}
26
27
// Ejecutar la lógica del filtro global
28
response.status(status).json({
29
statusCode: status,
30
timestamp: new Date().toISOString(),
31
path: request.url,
32
});
33
}
34
}

Crear Guardia global

1
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
2
import { Observable } from "rxjs";
3
4
@Injectable()
5
export class GlobalGuard implements CanActivate {
6
canActivate(
7
context: ExecutionContext,
8
): boolean | Promise<boolean> | Observable<boolean> {
9
const controller = context.getClass();
10
const controllerName = controller.name;
11
12
// Verificar si pertenece al controlador SpecialController
13
if (controllerName === "SpecialController") {
14
return true;
15
}
16
17
// Ejecutar la lógica de la guardia global
18
// ... Añadir tu lógica global aquí
19
return true;
20
}
21
}

Paso 5: Aplicar Interceptores, Filtros y Guardias globales en la aplicación principal

Registrar los interceptores, filtros y guardias globales en main.ts:

1
import { NestFactory } from "@nestjs/core";
2
import { AppModule } from "./app.module";
3
import { GlobalInterceptor } from "./global.interceptor";
4
import { GlobalFilter } from "./global.filter";
5
import { GlobalGuard } from "./global.guard";
6
7
async function bootstrap() {
8
const app = await NestFactory.create(AppModule);
9
app.useGlobalInterceptors(new GlobalInterceptor());
10
app.useGlobalFilters(new GlobalFilter());
11
app.useGlobalGuards(new GlobalGuard());
12
await app.listen(3000);
13
}
14
bootstrap();

Con estas modificaciones, el SpecialController dentro de SpecialModule no será afectado por los interceptores, filtros y guardias globales. Las demás rutas seguirán siendo manejadas por los interceptores, filtros y guardias globales.

Conclusión

Siguiendo estos pasos, hemos creado con éxito un SpecialModule especial y añadido lógica en los interceptores, filtros y guardias globales para omitir las rutas de SpecialModule. Espero que este artículo te sea útil en tu proyecto de NestJS.