Primeros endpoints
¿Qué es?
Un endpoint es una dirección concreta de tu API: una ruta (como /tareas) combinada con un método HTTP (como GET o POST). Cada endpoint es una puerta de entrada por la que un cliente pide o envía datos. En este módulo trabajamos con FastAPI, un framework de Python para construir esas puertas. Aquí defines tus primeras rutas y haces que tu programa responda a peticiones.
¿Cómo funciona?
Levantas un servidor que queda escuchando peticiones y, con un decorador como @app.get("/"), conectas una ruta a una función de Python. Cuando llega una petición a esa ruta, FastAPI ejecuta tu función y convierte lo que devuelves en una respuesta JSON automáticamente. Los datos de la petición llegan como argumentos de la función: en la ruta (path parameters) o después del ? (query parameters). Las anotaciones de tipo de Python le dicen a FastAPI cómo validar y convertir cada dato.
¿Para qué sirve?
Los endpoints son los ladrillos con los que se construye cualquier API: sin ellos no hay nada que pedir ni nada que responder. Dominar rutas, métodos y parámetros es el primer paso para que tus programas dejen de vivir solo en tu computador y empiecen a atender a otros. En el proyecto final, «API para tus herramientas», cada función que quieras exponer (registrar una nota, calificar una hoja) será un endpoint como los de aquí.
FastAPI es un framework para construir APIs con Python moderno. Se apoya en type hints (las anotaciones de tipo de Python) para validar datos, generar documentación interactiva y darte autocompletado en el editor. En este módulo levantas tu primer servidor, defines rutas, usas los métodos HTTP y aprendes a recibir parámetros. Es la base sobre la que construiremos el proyecto final, «API para tus herramientas».
Instalación y primer servidor
Crea un entorno virtual e instala FastAPI con el servidor uvicorn:
python -m venv .venv
source .venv/bin/activate # En Windows: .venv\Scripts\activate
pip install "fastapi[standard]"
El paquete fastapi[standard] ya incluye uvicorn, el servidor ASGI que ejecuta tu aplicación. Crea un archivo main.py:
from fastapi import FastAPI
app = FastAPI(title="API para tus herramientas")
@app.get("/")
def read_root():
return {"mensaje": "Hola, FastAPI"}
app es la instancia central de tu aplicación. El decorador @app.get("/") registra una operación de ruta: cuando llegue una petición GET a la ruta /, FastAPI ejecuta read_root y convierte el diccionario que devuelves en una respuesta JSON automáticamente.
Para correrlo:
fastapi dev main.py
# Alternativa equivalente: uvicorn main:app --reload
main:app significa «en el módulo main, la variable app». La opción --reload (o fastapi dev) reinicia el servidor cada vez que guardas un cambio. Abre http://127.0.0.1:8000 y verás el JSON. La joya de FastAPI está en http://127.0.0.1:8000/docs: una interfaz Swagger UI generada sola, donde puedes probar cada endpoint sin escribir un cliente.
Métodos HTTP
Cada método HTTP expresa una intención sobre un recurso:
GET: leer datos (no debe modificar nada).POST: crear un recurso nuevo.PUT/PATCH: reemplazar o actualizar parcialmente.DELETE: eliminar.
@app.get("/tareas")
def listar_tareas():
return [{"id": 1, "titulo": "Estudiar FastAPI"}]
@app.post("/tareas")
def crear_tarea():
return {"id": 2, "titulo": "Tarea nueva"}
Diseñar bien una API empieza aquí: usa sustantivos para los recursos (/tareas, /notas) y deja que el método HTTP exprese la acción. Evita rutas como /crearTarea; eso es lo que el POST ya comunica.
Parámetros de ruta
Los path parameters son partes variables de la URL. Se declaran con llaves y se reciben como argumentos tipados:
@app.get("/tareas/{tarea_id}")
def obtener_tarea(tarea_id: int):
return {"tarea_id": tarea_id}
El type hint tarea_id: int hace dos cosas: convierte el texto de la URL a entero y valida. Si alguien pide /tareas/abc, FastAPI responde un error 422 claro sin que escribas nada.
Parámetros de consulta
Los query parameters van después del ? en la URL. Cualquier argumento de la función que no esté en la ruta se interpreta como query:
@app.get("/tareas")
def listar_tareas(completada: bool | None = None, limite: int = 10):
return {"completada": completada, "limite": limite}
Una petición a /tareas?completada=true&limite=5 llega ya con completada=True y limite=5 convertidos. Al darles valor por defecto los vuelves opcionales.
Ejemplo guiado: mini API de notas
Vamos a exponer un sistema de notas, semilla directa del proyecto final.
from fastapi import FastAPI, HTTPException
app = FastAPI(title="API de notas")
NOTAS = [
{"id": 1, "estudiante": "Ana", "valor": 4.5},
{"id": 2, "estudiante": "Luis", "valor": 3.0},
]
@app.get("/notas")
def listar(min_valor: float = 0.0):
return [n for n in NOTAS if n["valor"] >= min_valor]
@app.get("/notas/{nota_id}")
def obtener(nota_id: int):
for nota in NOTAS:
if nota["id"] == nota_id:
return nota
raise HTTPException(status_code=404, detail="Nota no encontrada")
Pasos para probarlo:
- Guarda esto en
main.pyy correfastapi dev main.py. - Abre
http://127.0.0.1:8000/docs. - Despliega
GET /notas, pulsa Try it out, escribe4enmin_valory Execute. Solo debe volver Ana. - Prueba
GET /notas/2(devuelve a Luis) yGET /notas/99(devuelve 404 con tu mensaje).
HTTPException es la forma correcta de responder errores: defines el código y un detail legible. Una API útil no devuelve datos vacíos en silencio; explica qué pasó.
La diferencia entre path y query: el path identifica qué recurso (/notas/2); el query lo filtra o pagina (?min_valor=4). Si dudas, pregúntate si el dato forma parte de la identidad del recurso.
El orden de las rutas importa. Si declaras /notas/{nota_id} antes que /notas/resumen, una petición a /notas/resumen intentará convertir "resumen" a int y fallará con 422. Define primero las rutas fijas.
Tech English: endpoint = punto de acceso (una ruta + método). path parameter = parámetro de ruta. query parameter = parámetro de consulta. payload = los datos que viajan en la petición.
Ejercicios
-
API de libros. Diseña endpoints para una colección de libros:
GET /libroscon un query opcionalautorque filtre por autor, yGET /libros/{libro_id}que devuelva 404 con undetailútil si no existe. Evalúa: ¿los recursos están bien nombrados? ¿el filtro es query y el id es path? ¿el error explica el problema? -
Calificador de respuestas. Crea
GET /calificar/{respuesta}donde la ruta reciba la respuesta del estudiante y un querycorrectaindique la respuesta esperada; devuelve{"acierto": true/false}. Piensa qué tipos declarar para que FastAPI valide solo. Este endpoint es un primer borrador del calificador OMR del proyecto final.