> Manuales > Manual de NestJS

Cómo desarrollar validaciones con Nest Framework para rutas PATCH, reutilizando los DTO que hemos desarrollado para otros métodos como PUT y POST, por medio de la clase PartialType de @nestjs/mapped-types.

Validaciones en Nest en una ruta PATCH

En un artículo anterior vimos cómo aplicar ValidationPipe para realizar validaciones en los elementos que nos envían al backend por medio del body de la request.

Aprendemos a definir los DTO y luego estuvimos viendo cómo aplicar las reglas de validación sobre las propiedades de los DTO, y cómo hacer el uso de un pipe global. Todo eso entendemos que quedó claro. Ahora el objetivo es abordar una práctica necesaria en las API, que es la creación de rutas con el método PATCH.

Qué implica una ruta PATCH

El método de HTTP "PATCH" se usa para gestionar una solicitud en la que quieres hacer una actualización de un elemento, pero no quieres actualizar todos los campos de una vez, o quizás algunas veces lo hagas pero otras no. Dicho de otra manera, el método PATCH no te obligaría a mandar todos y cada uno los datos del recurso que quieres actualizar.

Para diferenciarlo del método PUT de HTTP, que resulta bastante similar, en PUT actualizaríamos todas las propiedades de un recurso y en PATCH actualizaríamos una o varias propiedades, no necesariamente todas.

¿Recuerdas cómo habíamos desarrollado el ProductDTO? (archivo "product.dto.ts") En este archivo indicamos que un producto contiene varias propiedades y, tal como fue programado, todas las propiedades son necesarias para que se valide correctamente una solicitud y se pueda ejecutar el método del controlador.

Entonces, volviendo al ejemplo que vimos en el artículo anterior, el DTO que presentamos nos podría servir perfectamente para las operaciones de POST y PUT, pero no podría servir para una ruta PATCH, dado que en principio en PATCH no se requiere recibir necesariamente todas las propiedades de un elemento.

Cómo reutilizar las reglas de validación en PATCH

Hemos dicho hace un instante que el DTO de POST o PUT no lo podemos utilizar tal cual en las rutas con el método PATCH. Pero claro, todo el trabajo que hemos hecho para poder definir las reglas de validación en el DTO no lo queremos hacer de nuevo en el DTO para PATCH. Obviamente, no queremos repetir código, sino reutilizar el trabajo hecho hasta ahora.

Por supuesto, copiar y pegar las reglas de validación no es una solución. Si lo hiciéramos, cuando queramos mantener el DTO, para agregar nuevas propiedades o modificar las existentes, tendrías que escribir o editar las reglas en dos archivos distintos.

Entonces ¿Cómo lo podemos reutilizar? para ello la organización de Nest nos ofrece una función aparte llamada PartialType que nos facilita todo el proceso. Básicamente permite reutilizar un DTO, pero indicando que las propiedades de los objetos serán siempre opcionales.

Para poder usar esta utilidad necesitamos hacer la instalación de un nuevo package llamado mapped-types.

npm i @nestjs/mapped-types

Una vez instalado mapped-types en nuestro proyecto, podemos continuar por crear el DTO nuevo, que consiste en una clase común de Javascript. Lo podemos hacer a mano o usar el comando:

nest g cl products/dto/product-patch.dto --no-spec

el DTO para el PATCH tendrá un código como este:

import { PartialType } from '@nestjs/mapped-types';
import { ProductDto } from './product.dto';

export class ProductPatchDto extends PartialType(ProductDto) { }

Como veis, no hay mucho código nuevo, lo que es genial para evitar trabajo extra en el mantenimiento. Simplemente reutilizamos lo que ya teníamos, ayudados de la herramienta comentada de "PartialType". El código es suficientemente claro, no obstante nos podemos fijar en estos puntos de interés:

Controlador para el método PATCH

Comparto el código del método del controlador que me hace la ruta de PATCH, para que quede claro que no tiene nada que no conozcamos ya.

@Patch(':id')
async patch(
  @Param('id', ParseIntPipe) id: number,
  @Body() body: ProductPatchDto,
) {
  return this.productsService.patch(id, body);
}

Método patch() en el servicio

Y ahora completamos el ejercicio creando un método en el servicio que se encarga de producir la actualización del elemento buscado.

patch(id: number, body: ProductPatchDto) {
  let previousProduct = this.getId(id);
  let product: Product = {
    ...previousProduct,
    ...body
  }
  this.products = this.products.map((item: Product) => {
    return item.id == id ? product : item;
  });
}

Este método tiene la particularidad de basarse en un método del propio servicio getId(). Ese método ya estaba preparado para que, si no se consigue el elemento buscado, porque no exista el id, entonces escala una excepción.

Ese servicio método fue desarrollado en artículos anteriores del Manual de Nest.

Luego generamos el nuevo objeto product, al que le asignamos las propiedades del producto previo y le mezclamos las propiedades del producto nuevo que recibimos en el parámetro body. Este código usa el Operador Spread de Javascript que seguramente ya conozcas.

Conclusión

Con esto hemos producido una ruta con el método PATCH. No la habíamos abordado en este manual todavía, pero nos ha dado pie a aprender algo bastante útil, que nos ha permitido reutilizar el código de las validaciones, o mejor dicho, las reglas de validación indicadas en el DTO de producto. Así podemos tener un único DTO para la entidad, dispensando la necesidad de tener un DTO para POST y PUT y otro distinto para PATCH.

En el siguiente artículo vamos a comentar algunas configuraciones útiles de ValidationPipe que podemos crear mediante opciones enviadas al constructor.

Miguel Angel Alvarez

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

Manual