Siempre me pasan cosas como: “Uh, otra vez tengo que inicializar todo el proyecto, configurar Express.JS (en el caso de Node.JS) ó Fastify, también crear la configuración de TypeScript, crear las carpetas, inyección de dependencias y un largo etcétera que muchas veces nos roban un montón de tiempo de nuestro proyecto, bueno, les traigo la solución.
¿Qué es NestJS?
Según su sitio web: “Nest (NestJS) es un framework para construir aplicaciones eficientes y escalables del lado del servidor en Node.js […] está construido con y soporta completamente TypeScript (aunque aún permite a los desarrolladores programar en JavaScript puro) y combina elementos de OOP (Programación Orientada a Objetos), FP (Programación Funcional) y FRP (Programación Reactiva Funcional).
Bajo el capó, Nest utiliza marcos de trabajo robustos de HTTP Server como Express (el predeterminado) y opcionalmente se puede configurar para usar también Fastify.
Nest proporciona un nivel de abstracción por encima de estos marcos comunes de Node.js (Express/Fastify), pero también expone sus APIs directamente al desarrollador. Esto brinda a los desarrolladores la libertad de usar la gran cantidad de módulos de terceros que están disponibles para la plataforma subyacente.”
Ya la definición nos habla mucho, al ser un framework nos obliga a tener que seguir sus lineamientos para poder usarlo, pero nos da una capacidad y rapidez que pocos nos dan.
La estructura de un proyecto, muchos términos y como funciona se parecen muchísimo a Angular (por ejemplo, pipes, interceptors, etc).
¿Cómo instalo NestJS?
Fácil, solo necesitamos tener npm instalado, luego correr el comando:
npm i -g @nestjs/cli
Más info: https://docs.nestjs.com/
Esto va a instalarnos un CLI que nos facilitará la vida… ¿Cómo?
Nest CLI
Básicamente el CLI hará todo el scaffolding del proyecto, es decir, crea todo lo necesario. Por ejemplo, con el comando:
nest new project-name
Creará un proyecto de NestJS con el nombre “project-name”.
Esto construye una lista de archivos y directorios necesarios para correr Nest.
Dentro del proyecto generado, podemos correrlo usando:
npm run start
Estructura de un proyecto de NestJS
Como mencioné antes, al correr el comando nest new nombreproyecto la estructura quedará algo así:
Dentro de src estará toda la lógica de nuestro proyecto. NestJS crea todo lo necesario para poder correr una API propia en segundos.
Lo que está por fuera son configuraciones y test más que nada.
Controladores, servicios y demás
El controlador por defecto que nos creará es algo como esto:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
A simple vista podemos ver varias cosas (de arriba hacía abajo).
Crea y exporta la clase AppController, pero arriba de esto hay un decorador @Controller(), este le indica a NestJS que la clase donde esta es un controlador, el framework lo utiliza para poder identificarlo y hacer X cosa con ellos.
En el constructor podemos ver que inyecta otra clase, llamada AppService, ya veremos qué es un servicio, pero podemos notar que por defecto, NestJS nos deja hacer uso de la inyección por dependencias de manera MUY FÁCIL. (Al igual que Angular).
Crea un método getHello() que retorna algo, pero si vemos arriba tenemos el decorador @Get(), esto indica que es un endpoint del tipo get, que podremos utilizar llamando a ese verbo.
En el controlador normalmente se estila a ser lo mas mínimo y posible en el código, toda la lógica de qué debemos hacer o retornar sobre el endpoint va en el servicio.
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
Este es nuestro servicio, como dije arriba, vamos a tener más lógica acá que en el controlador, por ejemplo las conexiones a las base de datos, el llamado a otros endpoints, etcetera.
Si vemos en la parte superior además de crear y exportar la clase AppService, tiene un decorador @Inyectable, esto le indica a Nest que esta clase puede ser inyectada en otra. Recordemos que una de las ventajas de la inyeccion de dependencias es olvidarnos de tener que construir un objeto para utilizarlo en otro.
Si bien no aparece en este código, obviamente se puede usar el constructor para inyectar otros servicios dentro.
Además de esto tenemos archivos de unit testing para los componentes (con Jest).
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
Algo importante de Nest, son los módulos. Este define de que clases está compuesto nuestro proyecto y nos permite modularizar por sector, de esta manera, solo importamos lo que necesitamos en ese mismo sin tener que “sobrecargar” nuestro código. Además de esta manera el framework sabe que controlador va con qué servicio, ó que servicio dentro de ese modulo es inyectable, etcetera.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Podemos ver que con el decorador @Module le indicamos que esta clase es un módulo, que controladores y providers lo componen y en caso de necesitar, podemos importar más modulos dentro. Esto nos ayudara mucho en el build también para no tener código repetido y pesado.
Otros componentes
Nest, además de los componentes por defecto posee varias cosas más:
En otro momento hablare más en detalle, pero son herramientas muy valiosas y útiles a la hora de usar este framework.
Conclusión
Sin duda alguna, NestJS es una excelente opción a la hora de hacer APIs, al ser un framework posee muchas ventajas y características de las cuales nos podemos aprovechar. En la documentación tenemos buenas prácticas y técnicas a la hora de usarlo que nos ayudaran mucho.