Hemos cubierto los métodos GET
para recuperar datos y POST
para crear nuevos recursos. Ahora, es el turno del método PUT
, un verbo HTTP esencial para actualizar recursos existentes en el servidor. A diferencia de POST
, que se usa para crear, PUT
se enfoca en modificar completamente un recurso ya presente, lo que implica una lógica de identificación y reemplazo. En esta lección, exploraremos cómo implementar métodos PUT
en los controladores de NestJS, incluyendo cómo identificar el recurso a actualizar y cómo manejar los datos de la solicitud.
Concepto de método PUT
En NestJS, como en el desarrollo de cualquier API RESTful, es crucial tener la capacidad de actualizar recursos existentes en el servidor. El método HTTP PUT está diseñado específicamente para este propósito. A diferencia de un POST (que suele crear un nuevo recurso), un PUT se utiliza para reemplazar completamente un recurso con los nuevos datos proporcionados, o crearlo si no existe en la URL especificada.
En términos sencillos, cuando envías una solicitud PUT, estás diciendo: "Aquí tienes la versión completa y actualizada de este recurso; por favor, guarda esta nueva versión en esta ubicación específica".
Uso de @Put()
en NestJS
Para manejar las solicitudes PUT en NestJS, se utiliza el decorador @Put()
en los métodos de un controlador. Este decorador se coloca sobre la función que ejecutará la lógica de actualización.
A continuación, se muestra cómo implementar un método PUT en un controlador utilizando NestJS.
Creación de un controlador básico
Primero, suponiendo que se tiene un recurso llamado "producto", se puede crear un controlador llamado productos.controller.ts
:
import { Controller } from '@nestjs/common';
@Controller('productos')
export class ProductosController {}
Implementación del método PUT
Ahora, dentro de este controlador, agregaremos un método para actualizar un producto usando el decorador @Put()
:
// src/productos/productos.controller.ts
import { Controller, Put, Body, Param } from '@nestjs/common';
@Controller('productos')
export class ProductosController {
// Simulación de una base de datos en memoria para el ejemplo
private productos: any[] = [];
@Put(':id')
actualizarProducto(@Param('id') id: string, @Body() productoDto: any): any {
// Lógica para actualizar el producto con el ID y los datos proporcionados
// En una aplicación real, interactuarías con una base de datos.
const index = this.productos.findIndex(p => p.id === id);
if (index > -1) {
this.productos[index] = { ...this.productos[index], ...productoDto, id };
return this.productos[index]; // Devolvemos el producto actualizado
}
// Si no existe, podrías crearlo (comportamiento idempotente de PUT)
const nuevoProducto = { id, ...productoDto };
this.productos.push(nuevoProducto);
return nuevoProducto;
}
}
Explicación de los decoradores:
@Put(':id')
: Este decorador indica que el métodoactualizarProducto
manejará las solicitudes PUT que lleguen a la ruta base del controlador (/productos
) seguida de un identificador dinámico (por ejemplo,PUT /productos/123
).@Param('id') id: string
: Este decorador extrae el valor del identificador de la URL (el:id
) y lo asigna a la variableid
de nuestro método.@Body() productoDto: any
: Este decorador se encarga de parsear el cuerpo de la solicitud HTTP (que normalmente contiene los datos JSON a actualizar) y lo asigna al parámetroproductoDto
. Aunque aquí usamosany
para un ejemplo básico, veremos cómo usar DTOs para una tipificación y validación robustas.
Uso avanzado de @Put()
en NestJS
A medida que las aplicaciones crecen en complejidad, se pueden utilizar más características de NestJS para mejorar y refinar la implementación de los métodos PUT.
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Validación del cuerpo de la solicitud
NestJS se integra a la perfección con librerías como class-validator
y class-transformer
para validar y transformar el cuerpo de la solicitud. Esto asegura que los datos enviados en una solicitud PUT cumplan con las reglas y estructuras esperadas antes de ser procesados.
Primero, creamos un DTO (Data Transfer Object) que define la estructura y las reglas de validación de los datos de nuestro producto
// src/productos/dto/producto.dto.ts
import { IsString, IsNotEmpty, IsNumber, IsOptional } from 'class-validator';
export class UpdateProductoDto {
@IsOptional() // Hacemos las propiedades opcionales para una actualización parcial
@IsString()
@IsNotEmpty()
nombre?: string; // Usamos '?' para indicar que la propiedad es opcional
@IsOptional()
@IsNumber()
precio?: number;
}
Luego, en el controlador, usamos este DTO en lugar de any
:
// src/productos/productos.controller.ts
import { Controller, Put, Body, Param } from '@nestjs/common';
import { UpdateProductoDto } from './dto/producto.dto'; // Importamos nuestro DTO
@Controller('productos')
export class ProductosController {
private productos: any[] = []; // Simulación de una base de datos
@Put(':id')
actualizarProducto(@Param('id') id: string, @Body() productoDto: UpdateProductoDto): any {
// ... lógica de actualización similar a la anterior, pero ahora con el DTO tipado
const index = this.productos.findIndex(p => p.id === id);
if (index === -1) {
// Podrías lanzar un error si no se encuentra o crear el recurso
// Para este ejemplo, si no existe, lo creamos (comportamiento idempotente de PUT)
const nuevoProducto = { id, ...productoDto };
this.productos.push(nuevoProducto);
return nuevoProducto;
}
this.productos[index] = { ...this.productos[index], ...productoDto, id };
return this.productos[index];
}
}
Con esta configuración, NestJS se encargaría automáticamente de validar que el cuerpo de la solicitud cumple con las reglas definidas en ProductoDto
. Si no es así, la solicitud sería rechazada automáticamente antes de llegar al método del controlador.
Manejo de errores
Es una buena práctica manejar posibles errores que puedan ocurrir durante el proceso de actualización (por ejemplo, que el recurso no exista).
NestJS proporciona un sistema de excepciones robusto para esto.
// src/productos/productos.controller.ts
import { Controller, Put, Body, Param, NotFoundException } from '@nestjs/common';
import { UpdateProductoDto } from './dto/producto.dto';
@Controller('productos')
export class ProductosController {
private productos = [ // Algunos productos de ejemplo
{ id: '1', nombre: 'Teclado', precio: 50 },
{ id: '2', nombre: 'Ratón', precio: 25 }
];
@Put(':id')
actualizarProducto(@Param('id') id: string, @Body() productoDto: UpdateProductoDto): any {
// Buscamos el producto por su ID
const index = this.productos.findIndex(producto => producto.id === id);
if (index === -1) {
// Si el producto no se encuentra, lanzamos una excepción NotFoundException
// NestJS la capturará y enviará una respuesta HTTP 404 Not Found.
throw new NotFoundException(`Producto con ID "${id}" no encontrado.`);
}
// Si el producto existe, actualizamos sus propiedades
this.productos[index] = { ...this.productos[index], ...productoDto, id };
// Devolvemos el producto actualizado. NestJS automáticamente lo serializará a JSON
// y enviará un código de estado HTTP 200 OK.
return this.productos[index];
}
}
En este ejemplo, si no se encuentra un producto con el ID especificado, se lanza una NotFoundException
. NestJS intercepta esta excepción y genera automáticamente una respuesta HTTP con un código de estado 404 Not Found, lo cual es un comportamiento estándar en APIs RESTful.
Conclusión
El uso de los métodos PUT en NestJS, combinado con la robustez de los DTOs para la validación (habilitada por el ValidationPipe
) y un manejo adecuado de excepciones, te permite construir APIs RESTful potentes y confiables. Al devolver directamente el recurso actualizado desde tus controladores, aprovechas el comportamiento idiomático de NestJS para simplificar la gestión de respuestas.
Aprendizajes de esta lección
- Comprender el propósito y el uso del método PUT en controladores de NestJS.
- Familiarizarse con los conceptos fundamentales del método PUT.
- Aprender cómo implementar un método PUT en un controlador de NestJS.
- Explorar el uso de DTOs (Data Transfer Objects) para validar y estructurar los datos enviados en una solicitud PUT.
- Conocer la importancia del manejo de errores en el contexto de solicitudes PUT.
Completa Nest y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs