> Manuales > Manual de NestJS

Qué son los controladores en las aplicaciones de NestJS. Explicamos el concepto de controlador y cómo se crean, usando el CLI de Nest. Veremos cómo crear rutas y cómo ejecutar la aplicación en modo desarrollo para actualizar cambios automáticamente.

Controladores en NestJS

En este segundo artículo del Manual de Nest vamos a comenzar con los controladores de la aplicación, a los que dedicaremos varios capítulos debido a su importancia.

En NestJS los controladores son una de las piezas principales de las aplicaciones. Básicamente nos sirven para dar soporte o responder las solicitudes realizadas al servidor. En este artículo aprenderemos cómo crear controladores y cómo atender diversas solicitudes.

Cómo crear controladores con el CLI de NestJS

Los controladores los podríamos crear a mano, ya que son simples archivos de código. Sin embargo, la CLI nos ofrece la posibilidad de crear el esqueleto de los controladores y aún encargarse de actualizar el código del módulo de la aplicación para registrar el uso de nuestro controlador.

Así pues, cada vez que queramos crear un nuevo controlador, lo normal será que invoquemos el correspondiente comando del CLI de Nest.

nest generate controller products

Como vemos, usamos el subcomando generate y seguido de la palabra "controller" y el nombre del controlador que queremos generar.

Podemos usar la abreviatura "g" en vez de "generate", y "co" en lugar de "controller" por lo que este comando sería equivalente:

nest g co products

Observarás que el controlador creado tiene el nombre "ProductsController", aunque en el comando de generación lo habíamos llamado simplemente "products".

El propio CLI te ofrece una salida indicando qué piezas de código ha creado y qué piezas de código ha actualizado.

CLI de NestJS, te informa de los archivos creados y modificados

Evitar que cree los archivos de pruebas

El proceso de crear el controlador ha generado un archivo extra, que igual no esperábamos, llamado "products.controller.spec.ts". Este archivo sirve para crear las pruebas unitarias de este controlador.

Si de momento no deseas que se cree automáticamente ese archivo puedes llamar al CLI con el flag "--no-spec".

nest g co customers --no-spec

Ver un preview de lo qué va a crear el CLI

Existe otro flag que puede ser útil llamado "--dry-run" que permite ver qué haría el generador de código del CLI antes que modifique ningún archivo en el sistema.

Este comando ofrece una salida similar a lo que habíamos visto a la hora de crear los archivos. Pero no modifica nada en el proyecto.

opción dry-run en el cli de nest

Colocar los controladores en otras rutas

Ahora vamos a suponer que necesitas crear una estructura de carpetas diferente a la que el CLI genera. Por ejemplo, quieres tener una carpeta "controllers" y en ella meter todos tus controladores.

Esto lo puedes hacer indicando al CLI la ruta del elemento que vas a crear, con un comando como sigue:

nest g co controllers/users

Como puedes ver en la salida, este controlador se habrá metido en la carpeta "controllers/users".

Cómo crear controladores en otras rutas

Registro de un controlador en el módulo

Gracias a que hemos creado el controlador por medio del CLI se ha registrado convenientemente dentro del módulo principal de la aplicación. Todo de manera automática.

Abre el archivo app.module.ts y podrás ver el controlador dentro de los archivos importados:

import { ProductsController } from './products/products.controller';

Y además, el controlador se ha añadido al array de "controllers" en el decorador @Module

@Module({
  imports: [],
  controllers: [AppController, ProductsController],
  providers: [AppService],
})

Si no usaras el CLI, tendrías que hacer todos estos pasos a mano, para actualizar el código del módulo donde estés asociando el controlador.

Código de nuestro controlador

Vamos ahora a comentar con más detalle el código que se ha generado para este controlador, que podemos ver a continuación.

import { Controller } from '@nestjs/common';

@Controller('products')
export class ProductsController {}

Lo primero es el import del decorador que hace posible que podamos convertir una clase en un controlador. Lo importamos desde '@nestjs/common'.

Luego tenemos una clase sin código alguno, de modo que es un controlador vacío, que de momento no atenderá ninguna ruta.

Vemos que la clase se ha decorado con @Controller('products'). Esto, como decimos, es muy importante para que NestJS le otorgue la condición de controlador a la clase que se está implementando. Pero todavía tienes que prestar atención al parámetro que le enviamos al controlador, la cadena 'products'. Esta cadena indica que nuestro controlador atenderá a rutas que están dentro de la carpeta 'products'. Dicho de otra manera, estará atendiendo el endpoint 'products'.

La carpeta donde hayas colocado este controlador dentro del proyecto no afecta al endpoint de este controlador. Solo afecta el parámetro que le enviamos al decorador.

Crear una ruta en el controlador

Ahora vamos a colocar algo de código nuestro en el controlador. Con lo poco que vimos en el artículo de introducción a NestJS ya tenemos una buena base para poder crear la ruta por nosotros mismos.

Básicamente vimos que en el controlador de inicio de la aplicación las rutas eran gestionadas por un método del controlador, en el que podemos poner el decorador @Get (también hay otros tipos de decoradores para rutas con otros verbos de HTTP).

Veamos cómo hemos creado nuestra primera ruta en el siguiente código.

import { Controller, Get } from '@nestjs/common';

@Controller('products')
export class ProductsController {

  @Get()
  getHelloInProducts(): string {
    return "Estamos en productos!!!";
  }
  
}

No te olvides de importar la declaración del decorador @Get, en el import correspondiente.

El método da igual cómo se llame. Simplemente se encarga de ejecutarse contra una request de tipo GET. En este caso estamos devolviendo una cadena directamente, que será suficiente para conseguir que el framework funcione.

En este caso, como el controlador fue decorado como @Controller('products'), la ruta a la que podemos acceder para ver lo que acabamos de hacer será: http://localhost:3000/products

¿No te funciona? posiblemente tengas que reiniciar el servidor. Vamos a hacer un paréntesis en la descripción de controladores para explicarlo en el siguiente punto.

Cómo arrancar el servidor en modo "watch"

El servidor de la aplicación lo arrancamos con el correspondiente comando del CLI. En el artículo anterior habíamos usado el script "start" de npm.

npm run start

Este script de npm por debajo invoca al CLI de Nest con este comando:

nest start

Aunque veamos que "npm run start" llama por debajo "nest start", es importante que se arranque el servidor mediante npm (y en general se invoquen los scripts de npm siempre), para asegurarte que te toma la versión del CLI de Nest que tienes instalada en local en este proyecto, en lugar de la versión global instalada en Node.

Este comando toma una instantánea de las rutas actuales de la aplicación y las comienza a servir. Sin embargo, a lo largo de la jornada iremos creando otros controladores con otras rutas y querremos que el servidor se actualice.

En lugar de parar el servidor y volverlo a arrancar podemos ejecutar el comando siguiente:

npm run start:dev

Que equivale al comando de Nest "nest start --watch", aunque nosotros lanzamos los comandos vía npm.

Por tanto ya lo sabes, si deseas que el propio servidor se refresque cuando vas actualizando el código de la aplicación, tendrás que lanzarlo con el flag "--watch". Es una utilidad muy interesante que te mejorará mucho el flujo de trabajo y que te ofrece NestJS sin necesidad de configuración alguna.

Cómo alterar el endpoint de una solicitud

El decorador @Get también recibe por parámetro de manera opcional la ruta del endpoint que vamos a generar.

Vamos a suponer que tenemos una ruta dentro de "products" que se llama "hot" para mostrar los productos más vendidos. La ruta completa sería "/products/hot". Entonces podemos simplemente crear ese método, enviando al decorador la parte de la ruta que queremos que se aplique en ese request.

@Get('hot')
getSpecialProducts(): string {
  return "Te vamos a mostrar los productos más calientes!!";
}

Ahora, si arrancas el servidor de nuevo, o mantienes la ejecución del mismo con el flag --watch, tal como te hemos enseñado, podrás acceder a la ruta http://localhost:3000/products/hot para ver la salida que hemos proyectado para este endpoint.

Conclusión

Hemos aprendido muchas cosas acerca de los controladores en NestJS. Claro que esto solo es el principio y gracias al framework podremos hacer muchas cosas más avanzadas, como gestionar otros tipos de rutas (POST, PUT…) o recibir parámetros.

Para continuar este manual en el siguiente artículo aprenderemos a gestionar parámetros en las rutas de los controladores Nest.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual