No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

16 Días
12 Hrs
26 Min
35 Seg

Pipe para mongoid

14/24
Recursos

En ocasiones es necesario validar nuestros propios datos de entrada. Cuando esos datos sean utilizados para realizar consultas a una base de datos, es recomendable estar prevenido por posibles ataques y validarlos manualmente.

Cómo validar ID de MongoDB

Los documentos que se crean en una base de datos MongoDB, por defecto, utilizan una propiedad llamada _id, o también llamado ObjectID, que representa el ID principal de cada documento. El mismo tiene un formato particular de 12 o 24 caracteres que podemos validar para asegurar que, el dato que el front-end nos envía, se trata efectivamente de un Mongo ID.

Paso 1: creamos el Pipe de NestJS

Crearemos un custom pipe con el comando nest g pi mongoId para validar el Mongo ID. El mismo contendrá la lógica del validador.

import { ArgumentMetadata, Injectable, PipeTransform, BadRequestException } from '@nestjs/common';
import { isMongoId } from 'class-validator';

@Injectable()
export class MongoIdPipe implements PipeTransform {

  transform(value: string, metadata: ArgumentMetadata) {
    if (!isMongoId(value)) {
      throw new BadRequestException(`${value} is not a mongoId`);
    }
    return value;
  }

}

Afortunadamente, la dependencia class-validator nos ayudará a validar el formato del string de entrada para verificar si posee la forma de un Mongo ID.

Paso 2: implementar el validador

Implementar un Pipe en NestJS es muy sencillo, basta con pasarlo como parámetro al decorador para que el mismo se ocupe de validar el dato de entrada.

import { MongoIdPipe } from './mongo-id.pipe';

export class ProductsController {
  
  @Get(':productId')
  getOne(@Param('productId', MongoIdPipe) productId: string) {
    return this.productsService.findOne(productId);
  }
}

Recuerda prestar atención tanto al tipado de datos para evitar errores como la validación de los mismos para mejorar la seguridad de tu aplicación. Las aplicaciones profesionales deben desarrollarse con las mejores prácticas posibles.

Contribución creada por: Kevin Fiorentino.


Código de ejemplo de pipe para mongoid

nest g pi common/mongoId
// src/common/mongo-id.pipe.ts

import {
  ArgumentMetadata,
  Injectable,
  PipeTransform,
  BadRequestException,
} from '@nestjs/common';
import { isMongoId } from 'class-validator';

@Injectable()
export class MongoIdPipe implements PipeTransform { // 👈 new pipe

  transform(value: string, metadata: ArgumentMetadata) {
    if (!isMongoId(value)) {
      throw new BadRequestException(`${value} is not a mongoId`);
    }
    return value;
  }

}
// src/products/controllers/products.controller.ts
import { MongoIdPipe } from './../../common/mongo-id.pipe'; // 👈 import

...
export class ProductsController {
  
  @Get(':productId')
  getOne(@Param('productId', MongoIdPipe) productId: string) {  // 👈 use MongoIdPipe
    return this.productsService.findOne(productId);
  }
}

Aportes 3

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Considero que éste punto es más de decisión propia. Ya que lo que uno quiere evitar es la consulta a la base de datos. Si mandamos un Id que no tiene el formato de ObjectId entonces mongo devolverá un producto nulo con el que nosotros enviamos un 404, lo cual es correcto ya que no existe y aún así Mongo evitó la consulta. Por ende por cuestiones de seguridad considero que es mejor devolver un 404 a un “is not mongoId”.
Ahora, a fines didácticos está perfecta la explicación. Incluso se podría hacer el NotFoundException en vez del BadRequest y funcionaría igual incluso con el pipe, sólo que ahí no llegamos hasta la instancia de tener que llamar al service.
No se qué opinan.

Si no les funciona el comando nest pueden usar

npx nest g pi 
common/mongoId

Este seria mi pipe

@Injectable()
export class ParseObjectIdPipe
  implements PipeTransform<any, mongoose.Types.ObjectId>
{
  transform(value: any): mongoose.Types.ObjectId {
    const validObjectId: boolean = mongoose.isObjectIdOrHexString(value);
    if (!validObjectId) {
      throw new BadRequestException('Invalid ObjectId');
    }
    return value;
  }
}