Consultar un cliente desde una API
Objetivos
Unirás FastAPI y SQLAlchemy para leer un registro y devolver una respuesta útil sin exponer operaciones de escritura.
Concepto
La ruta /customers/{customer_id} y el método GET forman un endpoint: el punto de acceso de la API que recibe el identificador pedido en la dirección web (URL). Session.get busca ese valor en la clave primaria. Si no existe el cliente, el servidor devuelve el estado HTTP 404 Not Found (recurso no encontrado), en vez de inventar un registro o tratar la ausencia como un fallo inesperado.
La cadena de conexión se configura en DATABASE_URL, una variable de entorno definida fuera del código para tu instalación local; nunca la escribas en el archivo ni la publiques en el repositorio.
Ejemplo
Instala el driver MySQL con python -m pip install fastapi uvicorn sqlalchemy pymysql. Asume que Customer es el modelo de la lección anterior y que get_db entrega una sesión cerrada al finalizar la solicitud:
from fastapi import Depends, FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session
from database import get_db
from models import Customer
app = FastAPI(title="Sakila Read API")
class CustomerOut(BaseModel):
customer_id: int
first_name: str
last_name: str
model_config = {"from_attributes": True}
@app.get("/customers/{customer_id}", response_model=CustomerOut)
def read_customer(customer_id: int, db: Session = Depends(get_db)) -> Customer:
customer = db.get(Customer, customer_id)
if customer is None:
raise HTTPException(status_code=404, detail="Cliente no encontrado")
return customerFastAPI obtiene una sesión para la solicitud y db.get(Customer, customer_id) busca una sola fila por su clave primaria. Si la encuentra, CustomerOut limita la respuesta a los campos declarados; si no, se genera el estado 404. La ruta solo lee: no recibe SQL del usuario ni ejecuta INSERT, UPDATE o DELETE.
Nota
Seguridad: el usuario de MySQL de la API debe tener permisos mínimos de lectura para las tablas canónicas. No pongas credenciales en ejemplos públicos.
Práctica guiada
- Solicita
/customers/1en tu instancia local de práctica con Sakila. - Solicita un identificador inexistente y confirma el estado
404. - Revisa que
CustomerOutexponga solo las tres columnas necesarias.
Reto
Agrega una ruta GET /customers que acepte un limit acotado entre 1 y 50 y devuelva resultados ordenados por customer_id. Conserva la conexión y la respuesta como operaciones de solo lectura.
Quiz
¿Qué debe responder el endpoint si db.get no encuentra el identificador?
- A.
404 Not Found. - B.
200 OKcon un cliente inventado. - C.
500en todos los casos.
Respuesta: A. Un recurso inexistente corresponde a 404.
Cierre del fixture
La ruta ya conecta estructura HTTP, modelo y una consulta de lectura. Antes de producción faltan configuración real de base de datos, límites de red, manejo de errores y pruebas de integración; este fixture no configura esos servicios.