No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Creando Data Transfers Objects

19/23
Recursos

NestJS utiliza el concepto de Objetos de Transferencia de Datos, o simplemente abreviado como DTO, para el tipado de datos y su segurizaci贸n.

Qu茅 son objetos de transferencia de datos o data transfers objects

Los DTO no son m谩s que clases customizadas que tu mismo puedes crear para indicar la estructura que tendr谩n los objetos de entrada en una solicitud.

1. Creando DTO

Crea un nuevo archivo que por lo general lleva como extensi贸n .dto.ts para indicar que se trata de un DTO.

// products.dto.ts
export class CreateProductDTO {
  readonly name: string;
  readonly description: string;
  readonly price: number;
  readonly image: string;
}

La palabra reservada readonly es propia de TypeScript y nos asegura que dichos datos no sean modificados.

Crea tantos atributos como tu clase CreateProductDTO necesite para dar de alta un nuevo producto.

2. Importando DTO

Importa la clase en tu controlador para tipar el Body del endpoint POST para la creaci贸n de un producto.

import { CreateProductDTO } from 'products.dto.ts';

@Post('product')
createProducto(@Body() body: CreateProductDTO): any {
    // ...
}

De esta forma, ya conoces la estructura de datos que tendr谩 el par谩metro body previo a la creaci贸n de un producto.

SRC: DTOS

// src/dtos/products.dtos.ts
export class CreateProductDto {
  readonly name: string;
  readonly description: string;
  readonly price: number;
  readonly stock: number;
  readonly image: string;
}

export class UpdateProductDto {
  readonly name?: string;
  readonly description?: string;
  readonly price?: number;
  readonly stock?: number;
  readonly image?: string;
}
// src/controllers/products.controller.ts
export class ProductsController {
  @Post()
  create(@Body() payload: CreateProductDto) { // 馃憟 Dto
    ...
  }

  @Put(':id')
  update(
    @Param('id') id: string,
    @Body() payload: UpdateProductDto  // 馃憟 Dto
   ) { 
   ...
  }

}
// src/services/products.service.ts
export class ProductsService {
  create(payload: CreateProductDto) { // 馃憟 Dto
    ...
  }

  update(id: number, payload: UpdateProductDto) { // 馃憟 Dto
    ...	
  }

}

Contribuci贸n creada por: Kevin Fiorentino.

Aportes 26

Preguntas 18

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Dejo un link interesante del querido Martin Fowler acerca de este patron https://martinfowler.com/bliki/LocalDTO.html

readonly???
el signo ? para variables opcionales???

Se ve que Typescript si que promete

La documentacion de Nest recomienda crear los DTOs con classes y no con interfaces.

  • Para que las validaciones sean tambien a nivel de ejecucion y no solo a nivel de desarrollo, podemos usar la lib interna de nest class-validator.
import { PartialType } from '@nestjs/mapped-types';
import { IsString, IsNumber, IsOptional, IsNotEmpty } from 'class-validator';

export class CreateProductDto {
  @IsNotEmpty()
  @IsString()
  readonly name: string;

  @IsString()
  @IsOptional()
  description?: string;

  @IsNotEmpty()
  @IsNumber({ allowNaN: false })
  price: number;

  @IsNotEmpty()
  @IsNumber()
  readonly stock: number;

  @IsString()
  readonly image: string;
}


export class UpdateProductDto extends PartialType(CreateProductDto) {
  @IsOptional()
  @IsString()
  readonly name?: string;

  @IsString()
  @IsOptional()
  description?: string;

  @IsOptional()
  @IsNumber({ allowNaN: false })
  price?: number;

  @IsOptional()
  @IsNumber()
  readonly stock?: number;

  @IsOptional()
  @IsString()
  readonly image?: string;
}

Funciones de los DTOs:

  • Proteger los datos
  • Validar y tipar datos
  • Evita hacer referencia a datos que no existan

Para no crear el IUpdateDto solo podrias utilizar algo como esto Partial<CreateProductDto>

Nico en tu m茅todo update de tu ProductsController haces una operaci贸n PUT pero en el ejemplo la operaci贸n no es de remplazo sino de actualizaci贸n parcial, es decir un PATCH

dejo un articulo al respecto: https://rapidapi.com/blog/put-vs-patch/

Data Transfers Objects

Los data transfers object o DTO por sus siglas, es una gu铆a para que el desarrollador y aquellos que consumen la API sepan que de forma espera tener el cuerpo de la solicitud.

No ejecuta ninguna validaci贸n de clases es mas una gu铆a

Creaci贸n de un DTO

Creamos una carpeta dtos en el cual creamos nuestro archivo products.dto.ts aqui vamos a especificar que campos van a obtener el cuerpo de la solicitud:

export class CreateProductDto {
	readonly name: string;
	readonly description: string;
	readonly price: number;
	readonly stock: number;
	readonly imag: string;
}

Readonly: Indica que el campo no podr谩 ser editado.

Y luego lo importamos en nuestro controlador o services:

import { CreateProductDto } from './../../dtos/products.dto'
@Post()
  create(@Body() payload: CreateProductDto) {
    return this.productsService.create(payload);
  }
Yo los veo como schemas

Los Data Transfers Objects (DTO) nos permite tipar y validar los datos que provienen de la petici贸n (body)

Entities vs DTOs

  • Entities may be part of a business domain. Thus, they can implement behavior and be applied to different use cases within the domain.
  • DTOs are used only to transfer data from one processor context to another. As such, they are without behavior - except for very basic and usually standardized storage and retrieval functions.

Fuente: https://www.linkedin.com/pulse/difference-between-entity-dto-what-use-instead-omar-ismail/?trk=pulse-article_more-articles_related-content-card

Estas son las grandes ventajas de TypeScript, en equipos grandes ayuda mucho porque ya sabes qu茅 tipo de dato esperar y el IntelliSense te dice exactamente lo que necesitas saber 馃槑

Con tipos tambi茅n funciona, y con partial convierto todos a valores opcionales:

export type ICreateProductDto = {
	readonly name: string;
	readonly description: string;
	readonly price: number;
	readonly stock: number;
	readonly image: string;
	readonly brand: string;
}

export type IUpdateProductDto = Partial<ICreateProductDto>;

Super interesante los DTOs, no conocia este concepto. Cuando trabajo con Angular, utilizo interfaces para tipar los payloads. Por ejemplo, en el caso del payload de productos yo haria lo siguiente:

export interface ProductRequest {
   name: string;
   description: string;
   stock: number:
   image: string;
}

funciona exactamente igual. Lo diferente, que me llamo la atencion es que con los DTOs puedes especificar que el atributo sea solo de lectura con readonly. Entonces esto da un mayor beneficio porque proteges mas los datos鈥uy interesante.

Definitivamente la 煤nica forma de aprender todo estos temas de configuraci贸n es poni茅ndolo en pr谩ctica en proyectos, peque帽os, medianos o grandes.

Te falto definir el 鈥淚d鈥 del producto en tu DTO, y el nombre de cada archivo DTO debe ser creado de manera 鈥淪ingular鈥.

Es una obra maestra esto de los DTO

No estas usando m茅todos de la clase, as铆 que puedes seguir usando interfaces con readonly, adicional yo suelo tener clases que tienen internamente un m茅todo que convierte a DTO (esto en el front), en Nest se podr铆a implementar una interfaz DTO, que la clase lo reciba en el constructor y lo guarde en el formato que necesita

Crear el dto del UpdateProducts

Validar el @body y el servicio con el Data Transfer Objects (dtos) nos aseguramos que nos envien los datos en los tipos correctos

Implementar el Data Transfers Objects (dto) en el Controlador

readonly - solo lectura no es para manipular

Crear datos de transferencia de productos

Data Transfers Objects son objetos que nos permiten validar (tipar informacion) cuando se env铆an datos de transferencia

Pero al final TypeScript solo es experiencia de desarrollo

Los DTO no serian igual que los types en el frront?