Introducción al framework Nest, una herramienta para el desarrollo de aplicaciones que se ejecutan bajo la plataforma Node. Explicamos las ventajas de NestJS y ofrecemos na vista de pájaro sobre la arquitectura de un proyecto inicial.
Con este artículo estamos comenzando el Manual de NestJS, el framework para desarrollo de aplicaciones del lado del servidor escalables y mantenibles, sobre la plataforma NodeJS.
Este framework permite desarrollar aplicaciones Backend usando la plataforma NodeJS, es decir, mediante el lenguaje Javascript para el servidor Además NestJS permite usar también Typescript, para mejorar todavía más las prestaciones para el desarrollador.
Por qué NestJS
Node es una plataforma de ejecución de Javascript bastante minimalista. Básicamente se trata de un intérprete de Javascript que permite ejecutar programas de consola, con propósito general.
Algunos frameworks de NodeJS, como Express, permiten realizar aplicaciones del lado del servidor, capaces de responder a solicitudes HTTP. Express se usa mucho para construir servicios web, como es el caso de APIs REST.
Express y otros frameworks NodeJS están muy bien, lo que ocurre es que dejan tradicionalmente muy suelto al desarrollador en lo que respecta a la arquitectura. Por ello el desarrollador acaba necesitando instalar diversas librerías, creando una estructura de carpetas que le sirva para sus necesidades, configurar las diversas herramientas, etc.
NestJS a diferencia de otros frameworks en Node tiene un foco en la arquitectura. Es decir, entrega ya un proyecto de base y unas herramientas configuradas que nos permiten evitar mucho del trabajo inicial de una aplicación en NodeJS. Además se trata de una arquitectura opinada, que nos garantiza buenas prácticas, mayor homogeneidad a los proyectos de las empresas y unas guías claras para los equipos de desarrollo.
Otro detalle a considerar sobre la arquitectura propuesta por Nest es su fuerte inspiración en Angular, por lo que resultará familiar para una buena comunidad de desarrolladores que ya conocen este framework.
NestJS está muy bien documentado y es sencillo aprender a manejar todos los entresijos del framework: https://docs.nestjs.com/
Qué ofrece NestJS
Como hemos dicho, Nest nos entrega todo el marco sobre el que vamos a desarrollar una aplicación. Gracias al framework tienes ya configurada la compilación de TypeScript y una serie de bibliotecas básicas. Además hace un uso intensivo de Programación Orientada a Objetos, lo que nos permite realizar un buen diseño de las aplicaciones.
Por debajo NestJS sigue trabajando con herramientas sólidas y conocidas del ecosistema NodeJS, como Express (y opcionalmente Fastify). Además permite trabajar con cualquier librería disponible en NodeJS que un proyecto necesite.
Otra de las ventajas de NestJS es que tiene su propio CLI, que nos permite crear cómodamente nuevos proyectos y realizar scaffolding de código por medio de comandos de consola, ejecutar cómodamente las aplicaciones y más.
En resumen, NestJS tiene como objetivo liberar al desarrollador de tareas comunes y repetitivas, ofrecer una arquitectura sólida para aplicaciones mantenibles y permitir preocuparse más del desarrollo y menos del setup de los proyectos.
Primeros pasos con Nest
NestJS requiere NodeJS 10.13.0 o superior. Sin embargo, nos advierten de no utilizar la versión 13 de Node.
Instalamos el CLI
Comenzamos por instalar el CLI de NestJS, que nos liberará de mucho trabajo en la generación de esqueletos de aplicaciones y sus componentes.
Para instalar el CLI de NestJS debemos lanzar este comando.
npm i -g @nestjs/cli
Una vez instalado podemos correr el comando "nest" para invocar el CLI. Algunos comandos que puedes probar son los siguientes:
Obtener la versión actual del CLI instalado:
nest -v
Obtener la lista de subcomandos de NestJS CLI:
nest --help
Crear un primer proyecto NestJS
Ahora que tenemos el CLI creamos un nuevo proyecto con el comando "nest new" seguido del nombre de la aplicación que vamos a crear.
nest new hola-mundo-nestjs
Una vez lanzado el comando seguimos el asistente, que nos pregunta el gestor de dependencias que queremos utilizar. Seleccionamos npm, o cualquier otra opción como Yarn si lo preferimos.
Ahora Nest se dedicará a instalar toda la estructura de aplicación e instalar todas las dependencias necesarias para funcionar.
Una vez instalado cambiamos a la carpeta del proyecto:
cd hola-mundo-nestjs
Luego lanzamos el comando de inicio del servidor de desarrollo:
npm run start
Una vez que la aplicación está lista y ejecutándose en nuestro ordenador podemos acceder a la URL del servidor que se ha levantado: http://localhost:3000/
Si todo ha ido bien, nos debería aparecer el mensaje "Hello World" en el navegador.
Estructura de un proyecto NestJS
En el momento que iniciamos el proyecto vemos que NestJS nos ha creado ya una cantidad de carpetas y archivos.
La mayoría de los archivos que dispone son relativos a la configuración del proyecto, ya sea el "package.json" para Node y npm, "tsconfig.js" para el TypeScript, etc.
El único archivo que te resultará novedoso es "nest-cli.json" que almacena información sobre la configuración del CLI y que no tendrás que tocar en un principio.
Carpeta src del proyecto
De entre todas las carpetas que tenemos encontramos una llamada "src" que es donde vas a estar trabajando para el desarrollo de los proyectos con Nest. Esta carpeta ya dispone de una cantidad de archivos iniciales, que son varios artefactos o piezas de software que usa NestJS para funcionar.
Vamos a ver una rápida descripción de los archivos que nos encontramos en esta carpeta, simplemente para ir familiarizándonos con ellos.
main.ts:
Este es el archivo que realiza el arranque de la aplicación. Todo comienza en el main.ts.
Contiene la importación del core de NestJS y el módulo principal de la aplicación (app.module). Luego realiza el propio arranque de la aplicación con la función bootstrap().
app.module.ts:
Es una clase, de Programación orientada a objetos, que observarás que no tiene ningún código en especial. Sin embargo está precedida de un decorador @module, que es el que hace que esta clase se comporte como un módulo de aplicación.
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
En el decorador @module se coloca toda la configuración del módulo. Observarás que se declara un controlador (propiedad "controllers") y un servicio (propiedad "providers"), que son otros de los dos archivos que se importan en esta clase y que también se encuentran en la carpeta src.
Si estás acostumbrado a trabajar con TypeScript y sobre todo con Angular estarás familiarizado con los decoradores, también llamadas "anotaciones". Básicamente los decoradores los podemos colocar antes de alguna estructura de código, como una clase, un método o atributo, y lo que permiten es colocar metadatos que sirven para configurar ese elemento que está siendo decorado.
A medida que vayamos construyendo más piezas de software en la aplicación se irán registrando en éste u otros módulos. Si construimos estas piezas con el CLI, como otros módulos, controladores o servicios, tenemos la ventaja de que se registren automáticamente en el código del módulo.
app.controller.ts:
Este es nuestro primer controlador de aplicación. Como quizás sepas de otros frameworks, los controladores son las piezas de software que se encargan de gestionar las solicitudes, realizando todo el trabajo necesario para gestionar el request y componer la respuesta.
Como puedes ver, el controlador es una clase, en la que colocamos el decorador @Controller. En el código de la clase observarás que tenemos un método, precedido de otro decorador @Get, que es el que se encarga de gestionar una solicitud (request de tipo GET). Esa, de momento, es la única ruta que se podrá atender en nuestra aplicación.
Otra cosa que vamos a destacar sobre este controlador es que usa un servicio llamado AppService. Este servicio está en otro archivo aparte que vamos a ver enseguida. Pero antes de ello queremos ver cómo este servicio es asociado al controlador.
Primero el servicio se tiene que importar, dado que está definido en otro archivo "ts".
import { AppService } from './app.service';
Luego, el servicio se inyecta mediante el constructor del controlador y se almacena como una propiedad privada al construir los objetos controller.
constructor(private readonly appService: AppService) {}
No te preocupes porque más adelante veremos con detalle y explicaremos todas estas líneas de código. De momento se trata solo de dar una vista de pájaro.
Seguramente si vienes de otros frameworks, o incluso conoces Angular, todo este proceso lo tendrás más o menos claro en una simple lectura del código. Si no es así, en breve te familiarizarás con esta manera de trabajar y te resultará bastante cómoda.
app.service.ts:
Este es el servicio que usaba el controlador. El servicio nuevamente es una clase, aunque en este caso el concepto de servicio está un poco infrautilizado, ya que tiene un simple método que devuelve una cadena. Ese método es getHello(), el que se invocó desde el controlador.
Lo interesante de este servicio es que está decorado con @injectable(). Básicamente este decorador permite que este servicio se pueda enviar al constructor de los controladores, mediante la inyección de dependencias que nos ofrece NestJS.
Conclusión
Hasta aquí hemos podido conocer NestJS, sus características y filosofía. Además hemos podido iniciar un proyecto y ofrecer una vista de pájaro sobre los componentes principales de esta aplicación inicial.
De momento es suficiente para un primer acercamiento a NestJS, pero obviamente estarás deseando meterle mano en el código y comenzar a crear tus primeras rutas personalizadas. No te preocupes porque en el siguiente artículo podrás aprender acerca de los controladores y mediante ellos podremos comenzar a ampliar esta aplicación de inicio.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...