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
You don't have access to this class
Keep learning! Join and start boosting your career
Creating your own data validations will be very important to secure your application and avoid unexpected errors.
Create your own PIPE to implement custom data validation logic.
With the NestJS CLI auto-generate a new pipe with the command nest generate pipe <pipe-name>
or in its short form nest g p <pipe-name>.
By default, you will see code like the following.
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable()export class ParseIntPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } } }
Implement your own data transformation and validation logic here. Note that if the data is invalid, you can throw exceptions to inform the front-end that the data is wrong.
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} is not a number.`); } return finalValue; } }
Finally, implement your custom PIPE in the driver.
import { ParseIntPipe } from './pipes/parse-int.pipe'; @Get('product/:idProduct') getProduct(@Param('idProduct', ParseIntPipe) idProduct: string): string { // ...}
You can develop the logic to validate and transform the data that best suits your needs. It is fundamental not to allow the input of erroneous data to your controllers. For that reason, the pipes are a previous layer to the controllers to make this validation.
nest g pi common/parse-int
// src/common/parse-int.pipe.tsimport { 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; } } }
Contributed by: Kevin Fiorentino.
Contributions 25
Questions 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
👏
Want to see more contributions, questions and answers from the community?