NestJS 11: Todas las novedades del framework backend de Node.js
NestJS 11 trae mejoras significativas en logging, microservicios, rendimiento y soporte para Express v5. Descubre todas las nuevas características.
NestJS 11 fue lanzado en enero de 2025, trayendo mejoras significativas orientadas a mejorar la experiencia del desarrollador y el rendimiento de las aplicaciones. En este artículo exploraremos todas las novedades de esta versión.
Logger Mejorado con Soporte JSON
El ConsoleLogger recibió una actualización importante con mejor formateo para objetos anidados, arrays, Maps y Sets. La característica más destacada es el soporte nativo para logging en formato JSON.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: {
json: true,
colors: process.env.NODE_ENV === 'development',
},
});
await app.listen(3000);
}
bootstrap();
Beneficios del JSON Logging
- Integración con herramientas de agregación como ELK Stack, Datadog o CloudWatch
- Parsing automatizado en entornos containerizados
- Búsqueda estructurada de logs en producción
- Compatibilidad con sistemas de monitoreo modernos
Mejoras en Microservicios
NestJS 11 introduce tres nuevos métodos poderosos para trabajar con microservicios:
Método unwrap()
Permite acceso directo a la instancia del cliente subyacente para operaciones personalizadas:
import { Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
@Injectable()
export class NotificationService {
constructor(private readonly client: ClientProxy) {}
async getUnderlyingClient() {
// Acceso directo al cliente NATS, Kafka, Redis, etc.
const natsClient = this.client.unwrap();
// Ahora puedes usar métodos nativos del cliente
return natsClient;
}
}
Método on() para Eventos
Escucha eventos internos como desconexiones para reaccionar en tiempo real:
@Injectable()
export class ConnectionMonitor implements OnModuleInit {
constructor(private readonly client: ClientProxy) {}
onModuleInit() {
this.client.on('disconnect', () => {
console.log('Conexión perdida con el broker');
// Lógica de reconexión o alertas
});
this.client.on('reconnect', () => {
console.log('Reconectado al broker');
});
}
}
Observable status
Proporciona actualizaciones dinámicas del estado de conexión:
@Injectable()
export class HealthService {
constructor(private readonly client: ClientProxy) {}
getConnectionStatus() {
return this.client.status.pipe(
map(status => ({
connected: status === 'connected',
status,
timestamp: new Date(),
}))
);
}
}
Los estados disponibles son:
connecting- Intentando conectarconnected- Conexión establecidadisconnected- Desconectadoreconnecting- Intentando reconectar
Optimización de Rendimiento en el Arranque
NestJS 11 reemplazó las funciones hash por referencias de objetos para generar claves opacas de módulos dinámicos. Esto mejora significativamente los tiempos de arranque en aplicaciones con muchos módulos dinámicos.
// Antes: El framework usaba hash functions (más lento)
// Ahora: Usa referencias de objetos (más rápido)
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync({
useFactory: (config: ConfigService) => ({
type: 'postgres',
host: config.get('DB_HOST'),
// ... más configuración
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
Nota: Este cambio trata módulos con configuración idéntica como instancias separadas en lugar de fusionarlos.
Nuevo ParseDatePipe
Un nuevo pipe para facilitar el trabajo con fechas:
import { Controller, Get, Query, ParseDatePipe } from '@nestjs/common';
@Controller('events')
export class EventsController {
@Get()
findByDate(
@Query('startDate', ParseDatePipe) startDate: Date,
@Query('endDate', ParseDatePipe) endDate: Date,
) {
return this.eventsService.findBetweenDates(startDate, endDate);
}
}
IntrinsicException
Nueva clase de excepción que omite el logging automático del framework:
import { IntrinsicException } from '@nestjs/common';
@Injectable()
export class AuthService {
async validateToken(token: string) {
if (!token) {
// Esta excepción NO será logueada automáticamente
throw new IntrinsicException('Token inválido');
}
// ...
}
}
Útil para:
- Errores sensibles que no deben aparecer en logs
- Validaciones donde el logging es innecesario
- Control granular sobre qué se registra
Mejoras en CQRS
El paquete @nestjs/cqrs ahora soporta:
Providers con Request Scope
@CommandHandler(CreateUserCommand)
@Injectable({ scope: Scope.REQUEST })
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
constructor(
private readonly request: Request, // Acceso al request actual
) {}
async execute(command: CreateUserCommand) {
// Lógica con acceso al contexto del request
}
}
Commands, Events y Queries Tipados
// Comando fuertemente tipado
export class CreateUserCommand implements ICommand {
constructor(
public readonly email: string,
public readonly name: string,
) {}
}
// Query fuertemente tipada
export class GetUserQuery implements IQuery {
constructor(public readonly id: string) {}
}
// El handler infiere los tipos correctamente
@QueryHandler(GetUserQuery)
export class GetUserHandler implements IQueryHandler<GetUserQuery, User> {
async execute(query: GetUserQuery): Promise<User> {
// query.id tiene tipo string
return this.userRepository.findOne(query.id);
}
}
Cambios en ConfigService
El ConfigService ahora lee valores en un orden diferente, permitiendo sobrescribir valores de process.env:
// config/app.config.ts
export default () => ({
port: 3000, // Este valor tiene prioridad sobre process.env.PORT
database: {
host: 'localhost',
},
});
// Nuevo: opción skipProcessEnv
@Module({
imports: [
ConfigModule.forRoot({
skipProcessEnv: true, // Ignora process.env completamente
load: [appConfig],
}),
],
})
export class AppModule {}
Soporte para Express v5 y Fastify v5
NestJS 11 actualiza las dependencias a las últimas versiones de Express y Fastify.
Migración de Express v5
La sintaxis de rutas wildcard cambió:
// Antes (Express v4)
@Get('/*')
findAll() {}
// Después (Express v5)
@Get('/*splat')
findAll() {}
// Caracteres opcionales
// Antes
@Get('/users/:id?')
// Después
@Get('/users{/:id}')
Cómo Actualizar
Para actualizar tu proyecto a NestJS 11:
# Actualizar dependencias core
npm install @nestjs/common@11 @nestjs/core@11 @nestjs/platform-express@11
# O con yarn
yarn add @nestjs/common@11 @nestjs/core@11 @nestjs/platform-express@11
# O con pnpm
pnpm add @nestjs/common@11 @nestjs/core@11 @nestjs/platform-express@11
Checklist de Migración
- Actualizar sintaxis de rutas wildcard si usas Express
- Revisar módulos dinámicos que dependían de la fusión automática
- Actualizar configuración del logger si necesitas JSON
- Revisar uso de
ConfigServicesi dependías del orden anterior
Conclusión
NestJS 11 representa una evolución importante del framework, con mejoras enfocadas en:
- Observabilidad: Logger JSON nativo para mejor integración con herramientas de monitoreo
- Microservicios: Mayor control y flexibilidad con
unwrap(),on()ystatus - Rendimiento: Arranque más rápido con la nueva generación de claves
- DX: Nuevos pipes, excepciones y mejoras en tipado
Si estás iniciando un nuevo proyecto, NestJS 11 es la mejor opción. Para proyectos existentes, la migración es relativamente sencilla, especialmente si no usas Express v5 wildcards.
Fuentes: