Endpoint PATCH para actualizar customers en FastAPI

Resumen

Actualizar registros en una API REST con FastAPI requiere algo más que cambiar un valor: implica elegir el método HTTP correcto, modelar los datos de entrada y devolver el código de estado adecuado. Aquí aprendes cómo construir un endpoint PATCH para modificar un customer en tu base de datos, manejando solo los campos que el usuario envía y refrescando la respuesta con los valores reales tras el commit.

Por qué usar PATCH en lugar de PUT para actualizar

Cuando necesitas modificar parcialmente un recurso, el método HTTP correcto es patch. A diferencia de un reemplazo total, patch te permite enviar únicamente los campos que quieres cambiar y deja intactos los demás.

En la práctica, partes del endpoint de lectura y lo duplicas como base, porque ambos comparten el mismo customer ID como parámetro de ruta. La diferencia clave es que patch recibe además un body con la información a actualizar [01:05].

¿Qué hace el método PATCH en una API? Actualiza parcialmente un recurso existente. Solo modifica los campos que envías en el body, dejando intactos los demás.

Cómo separar los modelos de creación y actualización

En los modelos del proyecto ya existe un customer base con nombre, descripción, email y los campos comunes, además de un customer create y la tabla customer con su ID. La buena práctica es duplicar el modelo create y renombrarlo como customer update.

¿Por qué tener dos modelos casi idénticos? Porque la creación y la actualización suelen comportarse distinto. Por ejemplo, al crear un usuario pides la contraseña, pero al actualizarlo ya no la solicitas de nuevo. Separar los modelos te da el espacio para esas diferencias sin romper la creación.

Una vez creado el modelo customer update, lo importas en el archivo del recurso y lo asignas como tipo del parámetro customer data en la firma del endpoint [02:30].

Qué declarar en la firma del endpoint PATCH

La función del endpoint necesita tres piezas claras:

  • El customer ID como parámetro de ruta para identificar a quién actualizar.
  • El customer data del tipo customer update para recibir los campos modificables.
  • Un tipo de respuesta customer, porque devuelves el registro completo ya actualizado.

Cómo aplicar los cambios con SQLModel update y exclude_unset

Con el ID en mano, primero ejecutas la query para obtener el customer DB desde la base de datos. Si existe, llega el momento de inyectarle los nuevos valores.

Para eso usas el método sqlmodel update, que recibe un diccionario con pares llave y valor. Ese diccionario lo generas a partir de los datos del usuario con customer_data.model_dump(), que convierte el modelo Pydantic en un dict listo para usar.

Aquí entra un detalle decisivo: el parámetro exclude_unset=True. Como se trata de un patch, solo quieres tocar los campos que el usuario envió. Si alguien manda únicamente el nombre, no debes sobrescribir descripción, email o edad con valores vacíos. Con exclude_unset el diccionario incluye solo los campos realmente enviados [04:10].

¿Para qué sirve exclude_unset en model_dump? Excluye del diccionario los campos que el usuario no envió, evitando que actualices con valores nulos los campos que no querías tocar.

Cómo persistir y refrescar el registro en la sesión

Llamar a sqlmodel update genera la actualización en memoria, pero no la guarda. Para persistirla necesitas tres pasos sobre la sesión de la base de datos:

  1. session.add(customer_db) para agregar la query a la sesión.
  2. session.commit() para confirmar los cambios en la base de datos.
  3. session.refresh(customer_db) para volver a cargar la variable con los valores ya actualizados.

El refresh es clave porque, aunque el commit escribe en la base, la variable customer_db aún conserva los datos originales de la query inicial. Sin refrescar, devolverías al cliente los valores viejos. Con session.refresh, la variable queda sincronizada con lo que realmente hay en la base [05:40].

Por qué devolver un status code 201 al modificar datos

Al probar el endpoint creas un customer llamado Sebastián con ID 1, lo actualizas a Wilson y la respuesta devuelve correctamente todos los campos modificados. Sin embargo, FastAPI por defecto responde con un status code 200.

La recomendación es explícita: siempre que hagas cambios en la base de datos, ajusta el código de respuesta para que refleje la operación. En el decorador del endpoint añades status_code=status.HTTP_201_CREATED, aprovechando que status ya está importado.

Con esto cierras el endpoint con tres elementos sólidos: el método patch, el modelo customer update tipando el body y el código 201 anunciando que sí hubo un cambio efectivo [07:00].

Qué sigue después de tener el CRUD completo

Con este patch ya cuentas con el CRUD completo: listar, crear, leer, borrar y actualizar. También has configurado un motor de base de datos, definido modelos con campos persistentes y separado modelos para personalizar entradas y salidas.

El siguiente reto es el crecimiento. Mantener todo en un solo archivo se vuelve incómodo cuando trabajas en equipo o cuando los recursos se multiplican. Por eso el paso natural es modularizar la aplicación: separar rutas, modelos y lógica para que el proyecto escale sin convertirse en un caos.

¿Has implementado un PATCH en tu propia API? Cuéntame en los comentarios cómo manejaste la actualización parcial de tus recursos.