Métodos PUT en controladores

Intermedio
Nest
Nest
Actualizado: 06/06/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

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étodo actualizarProducto 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 variable id 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ámetro productoDto. Aunque aquí usamos any 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.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

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

⭐⭐⭐⭐⭐
4.9/5 valoración