Usamos dos nuevos decoradores para las funciones de editar y eliminar un recurso, esto implementando @Put
y @Delete
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
El verbo HTTP GET se utiliza para la obtención de datos y el verbo POST para la creación de estos. También existe el verbo PUT y DELETE para la actualización y borrado de datos respectivamente.
El verbo PUT se usa para la actualización de un registro en la BBDD. Suele recibir un Body con los datos a actualizar, pero también es importante que reciba el ID del registro para buscar al mismo.
import { Controller, Put, Param, Body } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
@Put('product/:idProduct')
updateProducto(@Param('idProduct') idProduct: string, @Body() body: any): any {
return {
idProduct: idProduct,
name: body.newName,
price: body.newPrice
};
}
}
El ID suele recibirse por parámetros de URL para que sea obligatorio, mientras que reservamos el cuerpo del mensaje para los datos actualizados. Finalmente, retornamos el registro completo luego de ser actualizado.
Eliminar un registro es sencillo. Basta con decorar el endpoint con DELETE. Suele recibir el ID del registro a borrar únicamente.
import { Controller, Delete, Param } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
@Delete('product')
deleteProducto(@Param('idProduct') idProduct: string): any {
return {
idProduct: idProduct,
delete: true,
count: 1
};
}
}
Una buena práctica para este tipo de endpoints es retornar un booleano que indique si el registro fue eliminado o no. Además de incluir un count
que indique cuántos registros fueron eliminados.
src/controllers/products.controller.ts
import {..., Put, Delete } from '@nestjs/common';
@Controller('products')
export class ProductsController {
...
@Put(':id')
update(@Param('id') id: number, @Body() payload: any) {
return {
id,
payload,
};
}
@Delete(':id')
delete(@Param('id') id: number) {
return id;
}
}
Contribución creada por: Kevin Fiorentino.
Aportes 8
Preguntas 3
Usamos dos nuevos decoradores para las funciones de editar y eliminar un recurso, esto implementando @Put
y @Delete
PUT and DELETE
Estos dos métodos son increíbles , uno es para actualizar los datos y el otro es para eliminarlos
PUT
import { Controller, Delete } from '@nestjs/common';
Y lo agregamos de la siguiente manera
@Put(':id')
update(@Param('id') id: number, @Body() payload: any) {
return {
message: 'update method',
id,
payload,
};
}
DELETE
Como su mismo nombre lo dice es el método para eliminar datos
Este método usualmente se acompaña de un parámetro mínimo
Importamos
import { Controller , Delete } from '@nestjs/common';
Definimos
@Delete(':id')
delete(@Param('id') id: number) {
return {
message: 'Delete method',
id,
};
}
Para finalizar una excelente clase profe
Muchos devs también usan el PUT indistintamente del POST, pero esto no cumple con el standard, ademas hay otro aspecto importante que mencionar, la idempotencia de los verbos, un verbo es idempotente cuando la repetición de la acción no tiene repercusiones sobre el servidor, por esto se considera que PUT es idempotente, mientras que POST no lo es debido a que cada vez que repitas la peticion con este verbo tu api deberia crear un nuevo recurso.
Como se mencionó en la sesión, dependiendo del requerimiento un recurso podrá estar agrupando más características para culminar, de manera general, en CRUD.
.
Si bien, esto dependerá de nuestro desarrollo; se recomienda anexar tipos de respuesta y homologar la entrega de la misma para que en desarrollo se discuta funcionalidades y no detalles técnicos subjetivos.
.
En mi caso. tiendo anexar las siguientes respuestas:
// Single response
{
// ... object response definition
}
// Collection response
{
"results": [
{
// ... object response definition
},
]
}
También, anexando meta data como información adicional a la respuesta:
{
"info": {
"pages": 20,
"count": 843,
},
"results": [
{
// ... object response definition
},
]
}
.
.
.
.
Recuerde que el método patch
es un símil de edición y que el método put
nos permitirá una reconstrucción del objeto, pensado más para un lote de información y apoyándonos de valores por default establecidos en la Base de Datos.
.
La eliminación, por su parte, es definida como una funcionalidad con 2 efectos (que dependen de la definición de la base de datos para onDelete: cascade
).:
.
.
De lo anterior, se anexará la siguiente representación:
.
.
Donde adicionaremos a nuestro controlador la siguientes funcionalidades:
// controllers/publish.controller.ts
import {
Controller,
Post,
Patch,
Delete,
Param,
Body,
UsePipes,
ParseIntPipe,
HttpCode,
} from '@nestjs/common'
import { z } from 'zod'
import {
ZodValidationPipe,
createPublishSchema,
editPublishSchema,
} from '@validators/index.validator'
@Controller('post')
export class PublishController {
/**
* @description Create a new post. */
@Post()
@HttpCode(204)
@UsePipes(new ZodValidationPipe(createPublishSchema))
postPublish(@Body() publish: z.infer<typeof createPublishSchema>) {
console.log(publish)
}
/**
* @description Edit a post. */
@Patch(':id')
@HttpCode(204)
@UsePipes(new ZodValidationPipe(editPublishSchema))
patchPublish(
@Param('id', ParseIntPipe) id: number,
@Body() publish: z.infer<typeof createPublishSchema>
) {
console.log(publish)
}
/**
* @description Remove a post. */
@Delete(':id')
@HttpCode(204)
deletePublish(@Param('id', ParseIntPipe) id: number) {}
}
Nota. Se considera un código de respuesta específico para la edición por definición de nuestra plataforma para la edición de una publicación.
.
Así mismo, como interaccionamos con el body
de nuestra petición, anexaremos un nuevo esquema para validar la parcialidad de la petición de edición:
import { z } from 'zod'
export const createPublishSchema = z.object({
title: z.string().min(1).max(255),
description: z.string().min(1).max(255),
})
export const editPublishSchema = z.object({
title: z.string().min(1).max(255).optional(),
description: z.string().min(1).max(255).optional(),
})
Patch, es para puristas :v
En el delete se puede enviar una respuesta personalizada como
return {
message: `product ${id} deleted`,
};
Me ha estado gustando el curso desde el inicio, que buen contenido.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?