Implementando el Método PUT para Películas (Actualización)

 

Objetivo

Aprender a implementar el método PUT en una API RESTful para actualizar registros de películas existentes en la base de datos.


Paso 1: Configurar la Ruta PUT en el Archivo de Rutas

Vamos al archivo app.php (o routes/api.php dependiendo de tu estructura) y agregamos una nueva ruta:

php
// Ruta para actualizar una película existente
$app->put('/movies/{id}', function ($request, $response, $args) {
    // El parámetro {id} nos permitirá identificar qué película actualizar
    $id = $args['id'];
    
    // Llamamos al método correspondiente en el controlador
    $response->getBody()->write("Actualizando película con ID: $id");
    return $response;
});

Explicación:

  • Usamos put en lugar de post para indicar que es una operación de actualización

  • El parámetro {id} en la URL nos permite identificar el registro específico

  • Esta convención sigue los verbos HTTP estándar: POST para crear, PUT para actualizar


Paso 2: Crear el Método en el Controlador

En el controlador MovieController.php, creamos el método update:

php
<?php

class MovieController
{
    // Método para actualizar una película existente
    public function update(Request $request, Response $response, array $args)
    {
        // Obtenemos el ID desde los parámetros de la URL
        $id = $args['id'];
        
        // Buscamos la película en la base de datos
        $movie = Movie::findOrFail($id);
        
        // Actualizamos la película con los datos recibidos
        $movie->update([
            'title' => $request->getParam('title'),
            'director' => $request->getParam('director'),
            'year' => $request->getParam('year'),
            'genre' => $request->getParam('genre')
        ]);
        
        // Retornamos la respuesta
        $response->getBody()->write(json_encode([
            'message' => 'Película actualizada exitosamente',
            'movie' => $movie
        ]));
        
        return $response->withHeader('Content-Type', 'application/json');
    }
}

Paso 3: Entendiendo findOrFail()

¿Qué hace findOrFail()?

php
$movie = Movie::findOrFail($id);
  1. Busca un registro en la tabla movies con el ID especificado

  2. Si encuentra el registro, lo retorna como un objeto

  3. Si NO lo encuentra, automáticamente lanza una excepción

  4. En el contexto HTTP, esta excepción se traduce en un error 404 (Not Found)

Ventajas:

  • Código más limpio (no necesitamos verificar manualmente si existe)

  • Manejo automático de errores

  • Respuestas HTTP apropiadas


Paso 4: Actualizar la Ruta para Usar el Controlador

Actualizamos nuestra ruta para que use el método del controlador:

php
// Importar el controlador (si no está importado)
use App\Controllers\MovieController;

// Configurar la ruta PUT
$app->put('/movies/{id}', [MovieController::class, 'update']);

Paso 5: Probar con Postman

Configuración de Postman:

  1. Método: PUT

  2. URL: http://tudominio.com/movies/11

    • El número 11 es el ID de la película a actualizar

  3. Headers:

    text
    Content-Type: application/json
  4. Body (raw JSON):

    json
    {
      "title": "Gladiador 2",
      "director": "Ridley Scott",
      "year": 2024,
      "genre": "Acción/Drama"
    }

Respuesta Esperada:

json
{
  "message": "Película actualizada exitosamente",
  "movie": {
    "id": 11,
    "title": "Gladiador 2",
    "director": "Ridley Scott",
    "year": 2024,
    "genre": "Acción/Drama",
    "updated_at": "2024-01-15 10:30:00"
  }
}

Paso 6: Manejo de Errores (Mejora Opcional)

Podemos mejorar nuestro método para manejar validaciones:

php
public function update(Request $request, Response $response, array $args)
{
    try {
        $id = $args['id'];
        $movie = Movie::findOrFail($id);
        
        // Validar datos antes de actualizar
        $data = $request->getParsedBody();
        
        $validator = new Validator();
        $validation = $validator->validate($data, [
            'title' => 'required|max:255',
            'year' => 'required|integer|min:1900|max:' . date('Y')
        ]);
        
        if ($validation->fails()) {
            return $response->withJson([
                'errors' => $validation->errors()
            ], 422);
        }
        
        // Actualizar solo los campos que vienen en la petición
        $movie->fill($data);
        $movie->save();
        
        return $response->withJson([
            'message' => 'Película actualizada',
            'movie' => $movie
        ]);
        
    } catch (ModelNotFoundException $e) {
        return $response->withJson([
            'error' => 'Película no encontrada'
        ], 404);
    }
}

Puntos Clave Aprendidos

✅ PUT vs POST:

  • POST: Crear nuevos recursos

  • PUT: Actualizar recursos existentes

✅ Parámetros en URL:

  • Usamos {id} en la ruta para identificar el recurso

  • Accedemos con $args['id'] en el controlador

✅ findOrFail():

  • Método elegante para buscar registros

  • Maneja automáticamente el caso "no encontrado"

✅ Request Body:

  • Recibimos los datos a actualizar en formato JSON

  • Usamos $request->getParsedBody() para acceder a ellos

✅ Respuesta HTTP:

  • 200 OK: Actualización exitosa

  • 404 Not Found: Recurso no existe

  • 422 Unprocessable Entity: Datos inválidos


Próximo Paso: DELETE

En el siguiente tutorial aprenderemos a implementar el método DELETE para eliminar registros de la base de datos, completando así las operaciones CRUD (Create, Read, Update, Delete).


Consejo: Siempre verifica que el ID existe antes de intentar actualizar, y considera usar transacciones si tu actualización involucra múltiples tablas relacionadas.

Comentarios

Entradas más populares de este blog

Axios para Principiantes - Guía Paso a Paso

15-Tutorial: Crear Película en React con useState

Tutorial de React para Principiantes