Introducción a NestJS: Primeros pasos y estructura básica de un proyecto

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.

Autor: José Alvarado
Publicado: hace 4 días
Introducción a NestJS: Primeros pasos y estructura básica de un proyecto

¿Qué es NestJS?

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.

¿Por qué usar NestJS?

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:

  • Escalabilidad: Gracias a su arquitectura modular y su enfoque en la inyección de dependencias, NestJS permite crear aplicaciones escalables y fáciles de mantener
  • Productividad: NestJS proporciona una estructura de proyecto clara y bien definida, lo que facilita la organización del código y la colaboración entre equipos
  • Compatibilidad con TypeScript: Al estar basado en TypeScript, NestJS ofrece todas las ventajas de este lenguaje de programación, como tipado estático y autocompletado en el editor
  • Reutilización de código: NestJS cuenta con inyección de dependencias nativa, facilitando la reutilización de código y el mantenimiento de aplicaciones
  • Comunidad activa: NestJS cuenta con una comunidad activa de desarrolladores que contribuyen con librerías y herramientas para facilitar el desarrollo de aplicaciones

Comparación con otros frameworks

  • Express: NestJS se basa en Express y lo extiende con características adicionales, como la inyección de dependencias y la arquitectura modular
  • Fastify: Fastify es un framework de Node.js que se enfoca en la velocidad y el rendimiento, NestJS soporta Fastify como alternativa para mejorar el rendimiento

Instalación y primeros pasos

Requisitos previos

Antes de comenzar, asegúrate de tener instalado:

  • Node.js (Versión LTS recomendada)
  • npm (Administrador de paquetes de Node.js) o yarn (Alternativa a npm)

Instalación de NestJS

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

Creación de un nuevo proyecto

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.

Estructura básica de un proyecto de NestJS

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 ellas
    • app.controller.spec.ts: Archivo de pruebas unitarias para el controlador
    • app.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 datos
    • app.module.ts: Módulo principal de la aplicación, donde se definen los controladores, servicios y otros módulos
    • main.ts: Archivo de entrada de la aplicación, donde se crea la instancia de la aplicación y se inicia el servidor
  • test/: Directorio que contiene las pruebas unitarias y de integración de la aplicación
  • node_modules/: Directorio que contiene las dependencias del proyecto
  • eslin.config.mjs: Archivo de configuración de ESLint, una herramienta de análisis estático de código
  • nest-cli.json: Archivo de configuración del CLI de NestJS
  • package.json: Archivo de configuración de npm que contiene la información del proyecto y las dependencias
  • tsconfig.json: Archivo de configuración de TypeScript que define las opciones de compilación

Conceptos clave de NestJS

Controllers

Los 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';
  }
}

Services

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
  }
}

Modules

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 {}

Inyección de dependencias

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
  }
}

DTOs (Data Transfer Objects)

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.

Testing en NestJS

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']);
  });
});

Conclusión

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.