Puedes crear tus propios pipes para crear validaciones y transformaciones personalizadas.
Introducción a NestJS
¿Qué es NestJS?
Crea tu primer proyecto con NestJS
Estructura de aplicaciones en NestJS
Presentación del proyecto: Platzi Store
Repaso a TypeScript: tipos y POO
REST API
Introducción a controladores
GET: cómo recibir parámetros
GET: parámetros query
Separación de responsabilidades
Instalación de Postman o Insomnia
Qué es el método POST
Métodos PUT y DELETE para editar y eliminar
Códigos de estado o HTTP response status codes
Integridad de datos
Introducción a servicios: crea tu primer servicio
Implementando servicios en tu controlador
Manejo de errores con throw y NotFoundException
Introducción a pipes: usa tu primer pipe
Crea tu propio pipe
Creando Data Transfers Objects
Validando parámetros con class-validator y mapped-types
Cómo evitar parámetros incorrectos
Próximos pasos
Reto: controladores y servicios restantes
Continúa con el Curso de NestJS: Programación Modular
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Crear tus propias validaciones de datos será muy importante para segurizar tu aplicación y evitar errores inesperados.
Crea tu propio PIPE para implementar lógica custom de validación de datos.
Con el CLI de NestJS autogenera un nuevo pipe con el comando nest generate pipe <pipe-name>
o en su forma corta nest g p <pipe-name>
.
Por defecto, verás un código como el siguiente.
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return value;
}
}
Implementa aquí tu propia lógica de transformación y validación de datos. Ten en cuenta que si los datos no son válidos, puedes arrojar excepciones para informarle al front-end que los datos son erróneos.
import { ArgumentMetadata, Injectable, PipeTransform, BadRequestException } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
const finalValue = parseInt(value, 10);
if (isNaN(finalValue)) {
throw new BadRequestException(`${value} no es un número.`);
}
return finalValue;
}
}
Finalmente, implementa tu custom PIPE en el controlador.
import { ParseIntPipe } from './pipes/parse-int.pipe';
@Get('product/:idProduct')
getProduct(@Param('idProduct', ParseIntPipe) idProduct: string): string {
// ...
}
Puedes desarrollar la lógica para validar y transformar los datos que más se adecue a tus necesidades. Es fundamental no permitir el ingreso de datos erróneos a tus controladores. Por eso, los pipes son una capa previa a los controladores para realizar esta validación.
nest g pi common/parse-int
// src/common/parse-int.pipe.ts
import {
ArgumentMetadata,
Injectable,
PipeTransform,
BadRequestException,
} from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException(`${value} is not an number`);
}
return val;
}
}
Contribución creada por: Kevin Fiorentino.
Aportes 25
Preguntas 9
Puedes crear tus propios pipes para crear validaciones y transformaciones personalizadas.
nestjs se trae la esencia de angular, es una maravilla!
También puedes usar el objeto Number()
, para parsear la string numérica, con este objeto también evitas que parseInt te haga el parse cuando envías un número con letras.
Number()
Una curiosidad de parseInt(), que descubri probando (tal vez muchos ya la sepan, pero para mi es nuevo), es que si (en el argumento) tienes un string empezando por un numero y luego un caracter alfanumerico, devuelve el numero antes del primer caracter no numerico.
Ej.: si tienes
parseInt('12yletras')
devuelve --> 12
Bueno espero les sirva, saludos!
PD.: Me esta gustando mucho el curso hasta ahora! 👍️
Los pipes tienen dos funciones principales validar y transformar.
Importarlo
import { ParseIntPipe, } from '@nestjs/common';
Implementarlo
@Get(':productId')
@HttpCode(HttpStatus.ACCEPTED)
getProduct(@Param('productId', ParseIntPipe) productId: number) {
return this.productService.findOne(productId);
}
Tambien se puede crear un pipe customizable:
nest g pipe common/parse-int
CREATE src/common/parse-int.pipe.spec.ts (173 bytes)
CREATE src/common/parse-int.pipe.ts (224 bytes)
import { ArgumentMetadata, Injectable,PipeTransform, } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
return value;
}
}
import {
ArgumentMetadata,
Injectable,
PipeTransform,
BadRequestException,
} from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException(`${value} is not number`);
}
return val;
}
}
Pipes que tiene nestjs https://github.com/nestjs/nest/tree/master/packages/common/pipes
Agregue una validacion extra para el parseintpipe por que cuando ingresaba numeros con una letra o muchas letras no me lograba atrapar el error.
Este es mi codigo:
transform(value: string, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if (isNaN(val) || /\D/.test(value)) {
throw new BadRequestException(`${value} is not a number.`);
}
return val;
}
con el comando de la clase para el pipe se crea una subcarpeta, por lo que el import sería:
import { ParseIntPipe } from '../common/parse-int/parse-int.pipe';
Le pregunte a chatgpt como se testea ese pipe y me arrojo esto
import { ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ParseIntPipe } from './parse-int.pipe';
describe('ParseIntPipe', () => {
let pipe: ParseIntPipe;
beforeEach(() => {
pipe = new ParseIntPipe();
});
it('should be defined', () => {
expect(pipe).toBeDefined();
});
it('should transform a valid numeric string into an integer', () => {
const value = '42';
const metadata = {} as ArgumentMetadata;
const expectedOutput = 42;
const result = pipe.transform(value, metadata);
expect(result).toEqual(expectedOutput);
});
it('should throw a BadRequestException for an invalid numeric string', () => {
const value = 'invalid';
const metadata = {} as ArgumentMetadata;
expect(() => {
pipe.transform(value, metadata);
}).toThrow(BadRequestException);
});
});
Si queremos usar pipes con parametros o queries que son opcionales, podemos aplicar algo como esto:
products.controller.ts
@Get()
getProducts(
@Query('limit', new ParseIntPipe(false)) limit = 100,
@Query('offset', new ParseIntPipe(false)) offset = 0,
@Query('brand') brand: string,
) {
return this.productsService.findAll();
}
parse-int.pipe.ts
@Injectable()
export class ParseIntPipe implements PipeTransform {
constructor(private isRequired: boolean) {}
transform(value: string, metadata: ArgumentMetadata) {
const val = Number(value);
if (isNaN(val) && this.isRequired) {
throw new BadRequestException(
`Validation failed. ${value} is not a number`,
);
}
return val;
}
}
import { ArgumentMetadata, Injectable, PipeTransform, BadRequestException } from ‘@nestjs/common’;
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
const finalValue = parseInt(value, 10);
if (isNaN(finalValue)) {
throw new BadRequestException(${value} 👀 Tiene que ser de tipo numero el /id.
);
}
return finalValue;
}
}
ame este curso
Tambien es posible pasar varios Pipes, de esta manera
ya me dieron ganas de aprender angular
me pareció muy llamativa la validación que Nest hace para saber si es numérico un valor.
Se parece a los pipes de angular
Puedes crear tus propios pipes para crear validaciones y transformaciones personalizadas.
Desde la terminal ejecutamos el siguiente comando:
nest g pipe common/parse-int
Nos creara dentro de la carpeta common
dos archivos unos para el desarrollo de nuestro pipe y otro para la pruebas correspondientes
Dentro del archivo parse-int.pipe.ts
vamos a desarrollar un pipe para convertir de string a number:
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if(isNaN(val)){
throw new BadRequestException(`El valor is not an number`)
}
return val;
}
}
luego simplemente lo importamos en nuestro controlador y hacemos uso del pipe:
import { ParseIntPipe } from './../../common/parse-int.pipe'
@Get(':productId')
@HttpCode(HttpStatus.ACCEPTED)
getOne(@Param('productId', ParseIntPipe) productId: number) {
return this.productsService.findOne(productId);
}
es como Angular pero para el Backend!
Revisar el repositorio de Nest Js directamente en la carpeta Common puedes visualizar todos los PIPES ya pre-construidos por defecto.
Utilizar el PIPE que creamos para validar y transformar
Lanzar excepcion BadRequestException cuando no es posible transformar el dato al tipo correcto
Generar un nuevo PIPE (Validar y Transformar) desde el CLI
nest generate pipe common/parse-int -flat
👏
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?