NestJS es un framework progresivo de Node.js basado en TypeScript, diseñado para crear aplicaciones backend escalables y mantenibles. En este artículo exploraremos qué es NestJS, cómo instalarlo, su estructura básica y sus principales conceptos.
NestJS es un framework de backend (Aplicaciones del lado del servidor) basado en TypeScript que aprovecha el patrón de diseño modular y la inyección de dependencias para facilitar el desarrollo de aplicaciones escalables. Está inspirado en Angular y Spring, lo que le permite ofrecer una estructura de proyecto clara y bien definida.
NestJS es una excelente opción para aquellos desarrolladores que buscan una forma estructurada y organizada de construir aplicaciones backend en Node.js. Algunas de las ventajas de usar NestJS son:
Antes de comenzar, asegúrate de tener instalado:
Para crear un nuevo proyecto de NestJS, puedes utilizar el CLI (Command Line Interface) oficial de NestJS. El CLI te permite generar un proyecto base con una estructura predefinida y configuraciones iniciales. Para instalar el CLI de NestJS, ejecuta el siguiente comando:
npm install -g @nestjs/cli
Una vez instalado el CLI de NestJS, puedes crear un nuevo proyecto ejecutando el siguiente comando:
nest new my-project
Puedes reemplazar my-project
por el nombre que desees para tu proyecto. Al crear el proyecto, puedes elegir entre npm
, pnpm
o yarn
como administrador de paquetes.
Por último, accede al directorio del proyecto recién creado y puedes abrirlo en tu editor de código favorito.
Un proyecto de NestJS tiene una estructura de directorios y archivos bien definida. A continuación, se muestra un ejemplo de la estructura básica de un proyecto de NestJS:
my-project/
├── src/
│ ├── app.controller.ts
│ ├── app.controller.spec.ts
│ ├── app.service.ts
│ ├── app.module.ts
│ ├── main.ts
├── test/
├── node_modules/
├── eslin.config.mjs
├── nest-cli.json
├── package.json
├── tsconfig.json
A continuación, te explicaré brevemente la función de cada directorio y archivo en la estructura de un proyecto de NestJS:
src/
: Directorio que contiene el código fuente de la aplicación
app.controller.ts
: Controlador de la aplicación, encargado de manejar las peticiones HTTP, es decir, las rutas y los métodos asociados a ellasapp.controller.spec.ts
: Archivo de pruebas unitarias para el controladorapp.service.ts
: Servicio de la aplicación, encargado de la lógica de negocio, es decir, la implementación de las operaciones que realiza la aplicación como la consulta a una base de datosapp.module.ts
: Módulo principal de la aplicación, donde se definen los controladores, servicios y otros módulosmain.ts
: Archivo de entrada de la aplicación, donde se crea la instancia de la aplicación y se inicia el servidortest/
: Directorio que contiene las pruebas unitarias y de integración de la aplicaciónnode_modules/
: Directorio que contiene las dependencias del proyectoeslin.config.mjs
: Archivo de configuración de ESLint, una herramienta de análisis estático de códigonest-cli.json
: Archivo de configuración del CLI de NestJSpackage.json
: Archivo de configuración de npm que contiene la información del proyecto y las dependenciastsconfig.json
: Archivo de configuración de TypeScript que define las opciones de compilaciónLos controladores en NestJS son responsables de manejar las peticiones HTTP y generar las respuestas correspondientes. Cada controlador define una serie de rutas (endpoints) y métodos asociados a ellas. Por ejemplo, un controlador de usuarios podría tener rutas como /users
para obtener todos los usuarios y /users/:id
para obtener un usuario específico.
Ejemplo básico de un controlador en NestJS:
import { Controller, Get } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get()
findAll(): string {
return 'Get all users';
}
@Get(':id')
findOne(): string {
return 'Get user by id';
}
}
Los servicios en NestJS contienen la lógica de negocio de la aplicación, es decir, la implementación de las operaciones que realiza la aplicación. Los servicios se encargan de interactuar con la base de datos, realizar cálculos, enviar correos electrónicos, etc. Los servicios son inyectables, lo que significa que pueden ser utilizados en otros componentes de la aplicación, como controladores y otros servicios.
Ejemplo básico de un servicio en NestJS:
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
// Define una lista de usuarios (simulación de base de datos)
const users = ['User 1', 'User 2', 'User 3'];
findAll(): string {
return this.users; // Retorna todos los usuarios
}
findOne(): string {
return this.users[0]; // Retorna el primer usuario
}
}
Los módulos en NestJS son contenedores que agrupan los controladores, servicios y otros módulos relacionados. Cada aplicación de NestJS tiene al menos un módulo raíz, que se conoce como módulo principal. Los módulos permiten organizar y reutilizar el código de la aplicación de forma modular y escalable.
Ejemplo básico de un módulo en NestJS:
import { Module } from '@nestjs/common';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
La inyección de dependencias es un patrón de diseño que permite a los componentes de una aplicación solicitar las dependencias que necesitan en lugar de crearlas directamente. En NestJS, la inyección de dependencias se realiza de forma automática a través del contenedor de NestJS, que se encarga de crear las instancias de los componentes y gestionar sus dependencias.
Ejemplo de inyección de dependencias en un controlador de NestJS:
import { Controller, Get } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
// Inyecta el servicio de usuarios en el controlador
constructor(private usersService: UsersService) {}
@Get()
findAll(): string {
return this.usersService.findAll(); // Llama al método findAll del servicio de usuarios
}
@Get(':id')
findOne(): string {
return this.usersService.findOne(); // Llama al método findOne del servicio de usuarios
}
}
Los DTOs en NestJS son objetos que se utilizan para transferir datos entre los controladores y los servicios de la aplicación. Los DTOs permiten definir la estructura de los datos que se envían y reciben en las peticiones HTTP, lo que facilita la validación y la transformación de los datos. En otras palabras, los DTOs ayudan a validar los datos de entrada y salida de la aplicación.
Ejemplo de un DTO en NestJS:
import { IsString, IsNotEmpty } from 'class-validator';
export class CreateUserDto {
@IsString()
@IsNotEmpty()
name: string;
}
En este ejemplo, el DTO CreateUserDto
define una propiedad name
que debe ser una cadena de texto no vacía. Al utilizar DTOs en los controladores, se puede validar y transformar los datos de entrada de forma sencilla y segura antes de procesar los datos recibidos.
NestJS utiliza Jest como framework de pruebas por defecto. Jest es una herramienta de pruebas unitarias y de integración que facilita la escritura y ejecución de pruebas en aplicaciones de Node.js. Para escribir pruebas en NestJS, se pueden utilizar las funciones y métodos de Jest, así como las herramientas de NestJS para simular componentes y servicios.
Ejemplo de una prueba unitaria en NestJS:
describe('UsersService', () => {
it('debería retornar una lista de usuarios', () => {
const service = new UsersService();
expect(service.getUsers()).toEqual(['Usuario1', 'Usuario2']);
});
});
NestJS es un framework poderoso y flexible para construir aplicaciones backend escalables y mantenibles. En este artículo, hemos explorado los conceptos básicos de NestJS, su estructura de proyecto y algunos de sus componentes clave, como controladores, servicios y módulos. Además, hemos visto sobre los DTOs para validar los datos de entrada y salida de las aplicaciones, así como la importancia de las pruebas unitarias en el desarrollo de aplicaciones.
Si estás interesado en aprender más sobre NestJS, te recomiendo consultar la documentación oficial y explorar los ejemplos y tutoriales disponibles. Con NestJS, podrás construir aplicaciones backend robustas y escalables de manera eficiente y efectiva.