> Manuales > Manual de NestJS

Explicamos las maneras más básicas de personalizar los códigos de estado de las respuestas HTTP. Nest ofrece ya respuestas típicas de API REST, pero en las aplicaciones es normal necesitar alterar los status code de las respuestas.

Cómo cambiar el status de las respuestas HTTP con NestJS

En este artículo del Manual de Nest vamos a avanzar en la programación de nuestros controladores, aprendiendo algo tan básico y necesario en las aplicaciones API REST como es modificar los status de las respuestas.

El "status code" nos sirve para indicar a los clientes que van a usar estas API cómo ha ido la gestión de sus solicitudes, de modo que puedan representar convenientemente los mensajes de feedback necesarios para los usuarios en el lado del frontend.

El modelo de desarrollo por API REST tiene unos estados de respuesta digamos "estándar", dependiendo del tipo de solicitud y cómo han sido realizadas las operaciones en la ejecución de las mismas. Por tanto, debemos aprender a modificar los status de las respuestas para adecuarlos a los que se deberían esperar.

El propio NestJS ya nos ayuda bastante y ofrece status adecuados según el patrón REST, como por ejemplo el 201 cuando un recurso se ha podido crear después de una solicitud POST. Esto lo podemos comprobar dentro de Postman, en la salida derivada de la request que realizamos en el artículo anterior.

Cómo aparece un status code 201 en postman

Sin embargo, nosotros podemos cambiar los estados de la respuesta para adaptarlos a las necesidades, tal como vamos a aprender hoy.

Existen en Nest varios mecanismos para conseguir cambiar los estatus code de las respuestas. En este artículo vamos a conocer los más básicos que podemos usar, aunque más adelante explicaremos otros, basados en levantar excepciones, que también son muy útiles e incluso todavía más habituales en el desarrollo de las aplicaciones.

Decorador @HttpCode() para modificar el status de la respuesta

Para poder enviar nuestros estados de respuesta deseados podemos usar el decorador @HttpCode(), enviando como parámetro el número del estado necesario. Por ejemplo así:

@Post()
@HttpCode(204)
createProduct(@Body() body) {
  return body;
}

El status code 204 significa que no hay contenido. Quiere decir que la request se realizó correctamente y sin errores, pero que no hay ningún contenido que mostrar para el usuario. Típicamente sería usado en una operación de PUT en la que quieres informar al usuario que la edición se ha realizado de manera correcta, y que los datos que acaba de enviar son los que están actualmente almacenados en el sistema, por lo que no hay nada que mostrar, aparte de lo que está viendo ya.

HttpStatus contiene un listado de estados posibles status code

Para facilitar la legibilidad del código NestJS proporciona también una lista de estados con nombre en un enumerado llamado "HttpStatus".

Tanto el decorador @HttpCode como el enumerado HttpStatus los tienes que importar desde '@nestjs/common'.

Una vez importado el enumerado, gracias a TypeScript podrás ver todas las alternativas que nos ofrece en el propio editor, lo que facilita mucho para saber el nombre de cada estado.

Editor muestra los códigos de respuesta del enumerado httpStatus

En nuestra prueba vamos a seleccionar HttpStatus.NO_CONTENT, que equivale al status code 204. El código del método del controlador quedaría así:

@Post()
@HttpCode(HttpStatus.NO_CONTENT)
createProduct(@Body() body) {
  return body;
}

Volvemos a insistir: debes asegurarte de realizar los import de todas las declaraciones de decoradores o el enumerado que estamos usando. Dado el código anterior, en tu controlador deberías comenzar por realizar los siguientes import:

import { 
  Body, 
  Controller, 
  HttpCode, 
  HttpStatus, 
  Post 
} from '@nestjs/common';

A veces nos podemos olvidar de mencionar todo lo que debes importar, así que ve con cuidado y usa el editor para que te ayude a localizar las rutas o packages donde están las declaraciones que debes importar.

Ahora, si ejecutas la request, observarás en Postman que el estado de la respuesta ha cambiado para 204, tal como habíamos configurado.

ruta con status code 204

Ahora vamos a ver otro ejemplo de envío de un estado de respuesta 404. Nuevamente, para que el código sea más semántico, podemos usar el enumerado HttpStatus. En concreto, para el estado 404 tendremos que usar HttpStatus.NOT_FOUND.

En el siguiente código tenemos una ruta GET que devolverá siempre un status code 404, de página no encontrada.

@Get('ruta-error-404')
@HttpCode(HttpStatus.NOT_FOUND)
rutaConError404() {
  return 'Esto es un error 404!!';
}

Una vez accedemos desde Postman a esta ruta GET podremos ver la siguiente salida, donde aparece el error que estamos recibiendo.

Ruta de error 404

Cómo enviar códigos de error de manera condicional

En el ejemplo anterior hicimos uso de @HttpCode() definiendo en el decorador del método cuál iba a ser el status de la solicitud. Sin embargo, muchas personas podrán pensar que no es una manera realista de proceder, dado que durante la ejecución del método se puede dar el caso de enviar un código de respuesta unas veces y otro código en otras.

Por ejemplo, vamos a suponer que se trata de el acceso a un recurso por identificador. Ese recurso del ID enviado puede existir o no existir en una supuesta base de datos y por tanto el controlador puede necesitar enviar un status code condicional, que se decidirá según ha ido la ejecución del código. En caso que el recurso que se intenta acceder no exista tendremos que dar un código de respuesta de recurso inexistente. Sin embargo, si el identificador sí estaba presente en el sistema, el código de respuesta debería de ser otro.

Esto lo podemos gestionar en NestJS de diversas maneras, más o menos óptimas. En este artículo vamos a ver una posible solución que nos ayudará a salir del paso, aunque más adelante veremos otras alternativas que nos pueden facilitar las cosas todavía más.

Decorador @Res

Lo que vamos a aprender ahora es a usar un nuevo decorador, que nos permite recibir un objeto de "response", el cual podemos usar para definir la respuesta de la solicitud de una manera más detallada, incluyendo explícitamente un código de status determinado.

Para que veamos cómo trabajar con este objeto response vamos a ver el siguiente código, en el que recuperamos un método ya visto en un artículo anterior, de una solicitud GET en la que se mostraba un hipotético producto dado su identificador.

@Get(':id')
find(@Res() response, @Param('id') id: number) {
  if(id < 100) {
    return response.status(HttpStatus.OK).send(`Página del producto ${id}`);
  } else {
    return response.status(HttpStatus.NOT_FOUND).send(`Producto inexistente`);
  }
}

El decorador @Res no es muy usado realmente en las aplicaciones NestJS, ya que anula muchas de las funcionalidades que el framework ya proporciona. Es cierto que permite componer la respuesta de una manera más detallada, pero es de más bajo nivel y tendremos que realizar más cosas a mano. El camino para conseguir rutas condicionales en general se basa en excepciones, de las que hablaremos en breve.

Conclusión

Hemos aprendido a gestionar respuestas HTTP con su código de estado personalizado a nuestros intereses. El propio framework NestJS está preparado para enviar los códigos de respuesta más adecuados, atendiendo a la filosofía REST. Sin embargo, no tenemos necesidad de dejar al framework tomar la decisión y conformarnos con el código de respuesta implícito que él proporciona, sino que existen diversos métodos de alterar estos status code.

Hemos visto entonces algunos de los métodos posibles para enviar un código de respuesta personalizado, de manera fija en el método, y de manera condicional, usando un objeto "response", disponible en NestJS mediante el decorador @Res.

A lo largo del Manual de Nest hemos visto ya bastantes cosas sobre solicitudes POST y GET, asi que en el siguiente artículo abordaremos otros métodos del HTTP típicos de las API REST.

Miguel Angel Alvarez

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

Manual