Module 2: Path Operations

Introducción al Módulo 2: Path Operations

Descripción

En el módulo anterior levantaste un servidor FastAPI con endpoints GET y documentación automática. Ahora vas a dominar los verbos HTTP en la práctica. Implementarás endpoints POST para crear recursos, PUT y PATCH para actualizarlos, y DELETE para eliminarlos. Al final tendrás un CRUD completo — las cuatro operaciones que forman la base del 80% de las APIs en producción.

La diferencia entre este módulo y la guía de REST & HTTP (#5) es enorme: allá aprendiste que "POST es para crear recursos." Aquí vas a escribir el endpoint POST que recibe datos JSON, los almacena en memoria, y retorna el recurso creado con status code 201. Pasas de la teoría a la implementación real.


¿Dónde estamos en la guía?

Estás en el Módulo 2 de 6 de la guía FastAPI Fundamentals:

Módulo 1: Setup y Primera API ✅ (completado)
    → Instalación, uvicorn, endpoints GET, documentación automática

Módulo 2: Path Operations ← ESTÁS AQUÍ
    → GET, POST, PUT, PATCH, DELETE — CRUD completo

Módulo 3: Request y Response (siguiente)
    → Path params, query params, request body avanzado

Módulo 4: Pydantic y Validación
Módulo 5: Error Handling y CORS
Módulo 6: Proyecto Final — To-Do List API

Lo que ya dominas

Del Módulo 1 traes:

  • ✅ Virtual environment con FastAPI y uvicorn instalados
  • ✅ Estructura de proyecto app/main.py
  • ✅ Crear endpoints GET con decoradores
  • ✅ Path parameters con type hints
  • ✅ Hot reload con uvicorn
  • ✅ Probar endpoints en /docs

Lo nuevo de este módulo

  • 🆕 Endpoints POST con request body
  • 🆕 Endpoints PUT y PATCH para actualizar
  • 🆕 Endpoints DELETE para eliminar
  • 🆕 Datos en memoria (lista de diccionarios como mock database)
  • 🆕 Status codes específicos (201 Created, 204 No Content)
  • 🆕 Orden de evaluación de rutas en FastAPI

¿Qué es CRUD y por qué importa?

CRUD son las cuatro operaciones fundamentales sobre datos:

OperaciónVerbo HTTPDescripciónEjemplo
CreatePOSTCrear un recurso nuevoCrear un usuario
ReadGETLeer uno o varios recursosListar usuarios, ver perfil
UpdatePUT / PATCHModificar un recurso existenteCambiar nombre de usuario
DeleteDELETEEliminar un recursoBorrar una cuenta

¿Por qué dominar CRUD?

Prácticamente toda API en producción es una variación de CRUD. Una app de tareas: crear tarea, listar tareas, editar tarea, borrar tarea. Un e-commerce: crear producto, listar productos, actualizar precio, eliminar producto. Un sistema de usuarios: registrar, consultar perfil, actualizar datos, eliminar cuenta.

Si dominas CRUD, dominas el patrón que repite el 80% de tu trabajo como backend developer.

CRUD en FastAPI

FastAPI tiene un decorador para cada verbo HTTP:

@app.get("/items")        # Read (listar)
@app.get("/items/{id}")   # Read (detalle)
@app.post("/items")       # Create
@app.put("/items/{id}")   # Update (completo)
@app.patch("/items/{id}") # Update (parcial)
@app.delete("/items/{id}")# Delete

Cada decorador registra una ruta con su verbo correspondiente. La misma ruta /items/{id} puede tener diferentes comportamientos según el verbo HTTP usado.

El patrón de recursos REST

En REST, organizas tu API alrededor de recursos (sustantivos, no verbos). El recurso es "libros," y los verbos HTTP son las acciones sobre ese recurso:

Recurso: /books

POST   /books          → Crear un libro nuevo
GET    /books          → Listar todos los libros
GET    /books/{id}     → Obtener un libro específico
PUT    /books/{id}     → Reemplazar un libro completo
PATCH  /books/{id}     → Modificar campos de un libro
DELETE /books/{id}     → Eliminar un libro

Nota que la ruta es siempre /books (el recurso) — lo que cambia es el verbo HTTP. Esta convención la usarás en todas tus APIs.

Verbos HTTP en detalle

VerboIdempotenteTiene bodyDescripción
GETNoObtener datos sin modificar nada
POSTNoCrear un recurso nuevo
PUTReemplazar un recurso completo
PATCHNo*Modificar campos específicos
DELETENoEliminar un recurso

Idempotente significa que llamar la operación múltiples veces produce el mismo resultado. GET el mismo recurso 10 veces da lo mismo. DELETE el mismo recurso 10 veces: la primera lo borra, las demás no encuentran nada — pero el estado final es el mismo.

POST no es idempotente: cada llamada crea un recurso nuevo.

*PATCH técnicamente puede ser idempotente o no, dependiendo de la implementación.


Objetivo del módulo

Al completar este módulo serás capaz de:

  • ✅ Implementar endpoints GET para listar recursos y obtener uno por ID
  • ✅ Implementar endpoints POST que reciben JSON y crean recursos nuevos
  • ✅ Implementar endpoints PUT que reemplazan un recurso completo
  • ✅ Implementar endpoints PATCH que modifican campos específicos
  • ✅ Implementar endpoints DELETE que eliminan recursos
  • ✅ Usar una lista de diccionarios en memoria como almacenamiento temporal
  • ✅ Retornar status codes apropiados (200, 201, 204, 404)
  • ✅ Manejar el caso de "recurso no encontrado" de forma básica

Prerequisitos

Para este módulo necesitas:

  • Módulo 1 completado — Proyecto FastAPI funcionando con uvicorn
  • Conocimiento de HTTP verbs — Saber qué significan GET, POST, PUT, DELETE (Guía #5)
  • Tu proyecto del Módulo 1 — Lo abrirás y extenderás

Verificación rápida

# Tu proyecto debe existir y funcionar:
cd fastapi-fundamentals
source venv/bin/activate
uvicorn app.main:app --reload
# Debe levantar sin errores

Roadmap del módulo

CápsulaTemaQué aprenderás
01Introducción (esta cápsula)Contexto CRUD, roadmap, datos en memoria
02GET: Listar y obtenerGET list, GET detail, datos en memoria, orden de rutas
03POST: Crear recursosRequest body, crear items, IDs automáticos, status 201
04PUT, PATCH y DELETEActualizar completo/parcial, eliminar, status codes
05Proyecto: CRUD endpointsCRUD completo con datos realistas y todas las operaciones

Flujo de aprendizaje

Primero implementarás endpoints GET más sofisticados: listar una colección completa y obtener un recurso por ID, usando una lista de diccionarios como almacenamiento (Cápsula 02). Después agregarás POST para crear recursos nuevos, donde aprenderás cómo FastAPI maneja request bodies con JSON automáticamente (Cápsula 03). Luego completarás el CRUD con PUT, PATCH y DELETE, usando status codes apropiados para cada operación (Cápsula 04). Al final, integrarás todo en un CRUD completo con datos realistas (Cápsula 05).

La progresión es: leer → crear → actualizar → eliminar → integrar.

Detalle por cápsula

Cápsula 02 — GET: Listar y obtener: Crearás una "base de datos" en memoria usando una lista de diccionarios con datos de ejemplo. Implementarás GET para listar todos los items y GET por ID para obtener uno específico. Aprenderás sobre el orden de evaluación de rutas en FastAPI — un pitfall común.

Cápsula 03 — POST: Crear recursos: Aprenderás cómo FastAPI maneja request bodies. Implementarás POST que recibe JSON, genera un ID automático, y retorna el recurso creado con status 201. Probarás todo desde /docs.

Cápsula 04 — PUT, PATCH y DELETE: Completarás el CRUD implementando actualización completa (PUT), actualización parcial (PATCH), y eliminación (DELETE). Cada operación usa su status code correcto.

Cápsula 05 — Proyecto CRUD completo: Integrarás todas las operaciones en un CRUD con datos de libros — algo más realista que el Hello World del Módulo 1. Incluye verificación paso a paso, rúbrica de evaluación, y troubleshooting.


Cómo se ve el resultado final

Al terminar este módulo, podrás ejecutar este flujo completo desde /docs:

1. GET /books → Ver 5 libros precargados
2. POST /books → Crear "El Principito" (retorna con id: 6)
3. GET /books/6 → Verificar que existe
4. PATCH /books/6 → Cambiar solo "available" a false
5. GET /books/6 → Confirmar el cambio parcial
6. PUT /books/6 → Reemplazar todos los campos
7. DELETE /books/6 → Eliminar el libro
8. GET /books/6 → Confirmar que retorna error
9. GET /books → Confirmar que la lista tiene 5 libros

Este flujo es exactamente lo que un frontend haría contra tu API. Si todo funciona sin errores, tu CRUD está completo.

El código que escribirás

Tu app/main.py pasará de un Hello World a algo como esto:

from fastapi import FastAPI, Body

app = FastAPI(title="Books API", version="2.0.0")

books = [
    {"id": 1, "title": "Cien Años de Soledad", "author": "García Márquez", ...},
    {"id": 2, "title": "Don Quijote", "author": "Cervantes", ...},
    # ... más libros
]

@app.get("/books")            # Listar todos
@app.get("/books/{book_id}")  # Obtener uno
@app.post("/books")           # Crear
@app.put("/books/{book_id}")  # Actualizar todo
@app.patch("/books/{book_id}")# Actualizar parcial
@app.delete("/books/{book_id}")# Eliminar

Cada cápsula te guía para implementar estos endpoints uno por uno con código completo y probado.


Datos en memoria: Tu primera "base de datos"

Antes de entrar a las cápsulas técnicas, un concepto fundamental de este módulo: almacenamiento en memoria.

¿Por qué no usamos una base de datos real?

Porque este módulo es sobre routing y path operations, no sobre persistencia. Agregar una base de datos real ahora mezclaría dos complejidades innecesariamente. Las bases de datos vienen en guías posteriores del path.

¿Cómo funciona?

Usarás una lista de diccionarios como almacenamiento temporal:

# "Base de datos" en memoria
items = [
    {"id": 1, "name": "Laptop", "price": 999.99},
    {"id": 2, "name": "Mouse", "price": 29.99},
    {"id": 3, "name": "Keyboard", "price": 79.99},
]

Tus endpoints CRUD operarán sobre esta lista:

  • GET: Lee de la lista
  • POST: Agrega a la lista
  • PUT/PATCH: Modifica un elemento de la lista
  • DELETE: Remueve un elemento de la lista

Limitaciones (esperadas)

  • Los datos se pierden al reiniciar el servidor
  • No hay concurrencia segura
  • No hay búsqueda eficiente

Esto está bien para aprender. El objetivo es dominar FastAPI routing, no persistencia de datos.

La analogía

Imagina una pizarra blanca en una oficina. Puedes escribir items, borrar items, y modificar items. Pero si alguien limpia la pizarra (reinicia el servidor), todo desaparece. Una base de datos real es como grabar esos items en un disco duro — persisten. Por ahora, la pizarra es suficiente.

Los datos que usarás

En este módulo trabajarás con una colección de libros. Cada libro tiene:

{
    "id": 1,
    "title": "Cien Años de Soledad",
    "author": "Gabriel García Márquez",
    "year": 1967,
    "genre": "Realismo mágico",
    "available": True
}

¿Por qué libros? Porque son un dominio que todos entienden, tienen múltiples campos para practicar actualizaciones parciales (PATCH), y permiten filtros interesantes en el Módulo 3 (por género, por año, por disponibilidad).

Preparando tu proyecto

Antes de empezar las cápsulas técnicas, abre tu proyecto del Módulo 1:

cd fastapi-fundamentals
source venv/bin/activate

Vas a reemplazar el contenido de app/main.py. El Hello World API cumplió su propósito — ahora lo evolucionas a una Books API. Los conceptos del Módulo 1 (decoradores, path params, /docs) siguen aplicando, pero el contenido cambia.


¿Qué NO se cubre en este módulo?

  • Request body con Pydantic models — Se cubre en Módulo 4. Aquí usarás dicts simples
  • Query parameters avanzados — Se cubren en Módulo 3
  • HTTPException y error handling robusto — Se cubren en Módulo 5. Aquí manejas errores de forma básica
  • Bases de datos reales — Fuera del scope de esta guía
  • Autenticación — Se cubre en guía #9

¿Por qué estos límites?

  • Pydantic viene después porque primero necesitas endpoints funcionando. Agregar validación a algo que no existe es abstracto. Primero construyes, luego validas.
  • Error handling viene después porque primero necesitas operaciones que puedan fallar (ej: buscar un ID que no existe). Una vez que experimentas los problemas, la solución tiene sentido.
  • Query parameters vienen después porque primero necesitas datos sobre los cuales filtrar. Sin CRUD, no hay datos que filtrar.

Conexión con el proyecto final

El CRUD que construyas aquí es el core del To-Do List API (Módulo 6). Las operaciones son las mismas:

Módulo 2 (genérico):         Módulo 6 (To-Do List):
POST /items                  POST /tasks
GET /items                   GET /tasks
GET /items/{id}              GET /tasks/{id}
PUT /items/{id}              PUT /tasks/{id}
PATCH /items/{id}            PATCH /tasks/{id}
DELETE /items/{id}           DELETE /tasks/{id}

La diferencia es que el Módulo 6 tendrá validación Pydantic, error handling con HTTPException, filtros con query parameters, y CORS. Todo eso se agrega en módulos 3-5 sobre la base CRUD que construyes aquí.


Evidencia de éxito

Al terminar este módulo (las 5 cápsulas), sabrás que tuviste éxito si:

  • ✅ Puedes listar todos los items con GET y obtener uno por ID
  • ✅ Puedes crear un item nuevo con POST y ver que se agrega a la lista
  • ✅ Puedes actualizar un item existente con PUT (completo) y PATCH (parcial)
  • ✅ Puedes eliminar un item con DELETE y verificar que desaparece de la lista
  • ✅ Cada operación retorna el status code apropiado
  • ✅ Puedes probar todo el flujo CRUD desde /docs
  • ✅ Entiendes el orden de evaluación de rutas en FastAPI

Status codes que usarás

Cada operación tiene su status code convencional. En este módulo aprenderás a configurarlos:

OperaciónStatus CodeSignificadoConfiguración en FastAPI
GET200 OKRecurso encontradoDefault (no necesitas configurar)
POST201 CreatedRecurso creado exitosamente@app.post("/books", status_code=201)
PUT200 OKRecurso actualizadoDefault
PATCH200 OKRecurso parcialmente actualizadoDefault
DELETE200 OKRecurso eliminado (con confirmación)Default

En el Módulo 5 aprenderás status codes de error como 404 (Not Found) y 422 (Validation Error). Por ahora te enfocas en los exitosos.


Resumen

  • Este es el Módulo 2 de 6, enfocado en implementar las operaciones CRUD con FastAPI
  • CRUD (Create, Read, Update, Delete) es la base del 80% de las APIs en producción
  • Usarás datos en memoria (lista de dicts) como almacenamiento temporal
  • FastAPI tiene un decorador para cada verbo: @app.get, @app.post, @app.put, @app.patch, @app.delete
  • Los verbos HTTP siguen convenciones REST: rutas como sustantivos, verbos como acciones
  • Cada operación tiene su status code: 200 para lectura/actualización, 201 para creación
  • No se cubre validación Pydantic ni error handling avanzado — eso viene en módulos 4 y 5
  • El CRUD genérico que construyas aquí se transforma en el To-Do List API del Módulo 6
  • La progresión es: leer → crear → actualizar → eliminar → integrar

Recursos adicionales

  1. FastAPI - First Steps - Decoradores y path operations
  2. FastAPI - Request Body - Cómo FastAPI maneja request bodies
  3. HTTP Methods - MDN - Referencia completa de verbos HTTP
  4. REST API Design - Best Practices - Convenciones REST para CRUD
  5. FastAPI - Response Status Code - Status codes en FastAPI
  6. HTTP Status Codes - httpstatuses.com - Referencia visual de status codes


Cómo usar esta guía en el Módulo 2

  1. Abre tu proyecto del Módulo 1 en tu editor
  2. Activa el virtual environment (verificar que FastAPI está instalado)
  3. Reemplaza app/main.py con el código nuevo de cada cápsula
  4. Levanta uvicorn con --reload y deja la terminal corriendo
  5. Prueba cada endpoint en /docs después de implementarlo
  6. Haz los ejercicios al final de cada cápsula antes de avanzar

El flujo de trabajo es: leer → escribir código → probar en /docs → iterar.


Siguiente cápsula: GET: Listar y obtener recursos — Implementarás tus primeros endpoints de lectura con datos en memoria.