Entendiendo en Profundidad los Middleware en NestJS: Creación y Aplicación de Middleware para Manejar Solicitudes y Respuestas

  • 785Palabras
  • 4Minutos
  • 10 Jul, 2024

En NestJS, el middleware es un componente importante para manejar solicitudes y respuestas. Este artículo presentará en detalle el concepto de middleware en NestJS y explicará cómo crear y aplicar middleware para manejar solicitudes y respuestas.

¿Qué es el Middleware?

En NestJS, un middleware es una función que puede acceder al objeto de solicitud (req), al objeto de respuesta (res) y al siguiente middleware en el ciclo de solicitud-respuesta de la aplicación (next). Los middleware pueden realizar operaciones antes de procesar la solicitud, como autenticar usuarios, registrar logs, modificar el objeto de solicitud, etc.

La definición y uso de middleware es similar a Express.js, pero NestJS proporciona un soporte más robusto para la modularidad y la seguridad de tipos.

Creación de Middleware

Para crear un middleware, necesitas implementar la interfaz NestMiddleware y definir el método use. Aquí hay un ejemplo sencillo de un middleware de registro de logs:

1
import { Injectable, NestMiddleware } from "@nestjs/common";
2
import { Request, Response, NextFunction } from "express";
3
4
@Injectable()
5
export class LoggerMiddleware implements NestMiddleware {
6
use(req: Request, res: Response, next: NextFunction) {
7
console.log(`Request...`);
8
next();
9
}
10
}

En el ejemplo anterior, el middleware LoggerMiddleware registrará cada solicitud y llamará a la función next() para pasar el control al siguiente middleware o controlador de rutas.

Aplicación de Middleware

Para aplicar un middleware, puedes usar MiddlewareConsumer en el método configure del módulo para especificar el alcance del middleware. Aquí hay un ejemplo de cómo aplicar LoggerMiddleware a todas las rutas:

1
import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
2
import { LoggerMiddleware } from "./logger.middleware";
3
4
@Module({
5
// Otras configuraciones del módulo
6
})
7
export class AppModule implements NestModule {
8
configure(consumer: MiddlewareConsumer) {
9
consumer.apply(LoggerMiddleware).forRoutes("*");
10
}
11
}

El método apply especifica el middleware a aplicar, y el método forRoutes especifica el alcance del middleware. forRoutes('*') indica que el middleware se aplicará a todas las rutas.

Ejemplos de Middleware

Modificar el Objeto de Solicitud

El siguiente middleware agrega una propiedad personalizada customProperty al objeto de solicitud:

1
import { Injectable, NestMiddleware } from "@nestjs/common";
2
import { Request, Response, NextFunction } from "express";
3
4
@Injectable()
5
export class CustomPropertyMiddleware implements NestMiddleware {
6
use(req: Request, res: Response, next: NextFunction) {
7
req["customProperty"] = "Custom Value";
8
next();
9
}
10
}

Modificar el Objeto de Respuesta

Aquí hay un ejemplo de un middleware que modifica el objeto de respuesta:

1
import { Injectable, NestMiddleware } from "@nestjs/common";
2
import { Request, Response, NextFunction } from "express";
3
4
@Injectable()
5
export class ResponseModifierMiddleware implements NestMiddleware {
6
use(req: Request, res: Response, next: NextFunction) {
7
res.on("finish", () => {
8
console.log("Response finished");
9
});
10
next();
11
}
12
}

Colaboración entre Múltiples Middleware

Varios middleware pueden trabajar juntos, cada uno realizando sus propias operaciones. Aquí hay un ejemplo de uso de LoggerMiddleware y CustomPropertyMiddleware juntos:

1
import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
2
import { LoggerMiddleware } from "./logger.middleware";
3
import { CustomPropertyMiddleware } from "./custom-property.middleware";
4
5
@Module({
6
// Otras configuraciones del módulo
7
})
8
export class AppModule implements NestModule {
9
configure(consumer: MiddlewareConsumer) {
10
consumer.apply(LoggerMiddleware, CustomPropertyMiddleware).forRoutes("*");
11
}
12
}

En el ejemplo anterior, LoggerMiddleware registrará logs de las solicitudes y CustomPropertyMiddleware agregará una propiedad personalizada al objeto de solicitud. Todas las solicitudes pasarán por estos dos middleware.

Uso de forRoutes y exclude

El método forRoutes puede especificar que el middleware se aplique a rutas, controladores o métodos específicos.

Aplicar a Rutas Específicas

1
consumer
2
.apply(LoggerMiddleware)
3
.forRoutes({ path: "cats", method: RequestMethod.GET });

Aplicar a Controladores Específicos

1
import { CatsController } from "./cats.controller";
2
3
consumer.apply(LoggerMiddleware).forRoutes(CatsController);

Aplicar a Múltiples Rutas y Métodos

1
consumer
2
.apply(LoggerMiddleware)
3
.forRoutes(
4
{ path: "cats", method: RequestMethod.GET },
5
{ path: "dogs", method: RequestMethod.POST },
6
);

Excluir Rutas Específicas

El método exclude se usa para excluir rutas específicas del middleware:

1
consumer
2
.apply(LoggerMiddleware)
3
.exclude(
4
{ path: "cats", method: RequestMethod.GET },
5
{ path: "dogs", method: RequestMethod.POST },
6
)
7
.forRoutes("*");

En el ejemplo anterior, LoggerMiddleware se aplicará a todas las rutas excepto GET /cats y POST /dogs.

Middleware Funcional

Además de los middleware de clase, NestJS también soporta la creación de middleware usando funciones. Aquí hay un ejemplo de middleware funcional:

1
import { Request, Response, NextFunction } from "express";
2
3
export function logger(req: Request, res: Response, next: NextFunction) {
4
console.log(`Request...`);
5
next();
6
}

Al usar middleware funcional, no necesitas implementar la interfaz NestMiddleware. Puedes aplicarlo directamente en el módulo:

1
import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
2
import { logger } from "./logger.middleware";
3
4
@Module({
5
// Otras configuraciones del módulo
6
})
7
export class AppModule implements NestModule {
8
configure(consumer: MiddlewareConsumer) {
9
consumer.apply(logger).forRoutes("*");
10
}
11
}

Conclusión

Este artículo ha presentado en detalle el concepto de middleware en NestJS y ha explicado cómo crear y aplicar middleware para manejar solicitudes y respuestas. Al usar middleware, los desarrolladores pueden realizar varias operaciones en el proceso de manejo de solicitudes, como autenticación, registro de logs y modificación de solicitudes, mejorando así la funcionalidad y seguridad de la aplicación. También hemos mostrado ejemplos de colaboración entre múltiples middleware, cómo modificar los objetos de solicitud y respuesta, y cómo usar los métodos forRoutes y exclude para controlar el alcance del middleware. Además, hemos introducido la creación y aplicación de middleware funcional.