Concepto clave
Integrar MongoDB con FastAPI para escenarios NoSQL significa aprovechar la flexibilidad de esquemas y la escalabilidad horizontal que ofrecen las bases de datos documentales. En el mundo real, imagina una red social donde cada usuario tiene un perfil único con campos variables: algunos tienen educación detallada, otros hobbies extensos, y otros prefieren mantenerlo minimalista. MongoDB permite almacenar estos documentos sin forzar un esquema rigido, similar a como organizarias archivos en carpetas flexibles en lugar de tablas fijas.
El motor asíncrono de MongoDB (Motor) es crucial para aplicaciones de alto rendimiento. A diferencia de las operaciones sincrónicas que bloquean el hilo de ejecución esperando respuestas de la base de datos, el enfoque asíncrono permite que FastAPI maneje múltiples solicitudes simultáneamente, mejorando la eficiencia en escenarios como APIs con miles de usuarios concurrentes. Es como tener un equipo de mensajeros que entregan paquetes sin detener la oficina principal, en lugar de un solo mensajero que hace todo secuencialmente.
Cómo funciona en la práctica
Para integrar MongoDB con FastAPI, seguimos un flujo estructurado que garantiza robustez y mantenibilidad. Primero, configuramos la conexión asíncrona usando Motor, definiendo una URL de conexión que incluya credenciales y opciones como timeouts. Luego, creamos modelos Pydantic para validar y serializar datos, aprovechando que MongoDB usa documentos BSON pero trabajamos con objetos Python. Finalmente, implementamos operaciones CRUD asíncronas en rutas FastAPI, manejando excepciones específicas de MongoDB como DuplicateKeyError.
Un ejemplo paso a paso: 1) Instalar dependencias (fastapi, uvicorn, motor, pymongo). 2) Configurar variables de entorno para la URI de MongoDB. 3) Crear un cliente asíncrono en un módulo de base de datos. 4) Definir esquemas Pydantic con tipos opcionales para campos flexibles. 5) Implementar endpoints con decoradores FastAPI y funciones async. 6) Probar con herramientas como Postman o curl, verificando respuestas JSON y códigos de estado.
Codigo en accion
Configuración inicial de la conexión:
# database.py
from motor.motor_asyncio import AsyncIOMotorClient
import os
MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017")
client = AsyncIOMotorClient(MONGO_URI)
database = client["fastapi_db"]
users_collection = database["users"]Antes: Usar conexión sincrónica que bloquea el evento loop. Despues: Conexión asíncrona que mejora el rendimiento.
Endpoint para crear un usuario:
# main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import Optional
from database import users_collection
from bson import ObjectId
app = FastAPI()
class UserCreate(BaseModel):
name: str
email: str
age: Optional[int] = None
metadata: Optional[dict] = {}
class UserResponse(UserCreate):
id: str
class Config:
json_encoders = {ObjectId: str}
@app.post("/users/", response_model=UserResponse)
async def create_user(user: UserCreate):
try:
result = await users_collection.insert_one(user.dict())
user_data = user.dict()
user_data["id"] = str(result.inserted_id)
return UserResponse(**user_data)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error creating user: {str(e)}")Errores comunes
- No manejar ObjectId en respuestas JSON: MongoDB devuelve _id como ObjectId, que no es serializable directamente a JSON. Solución: Convertir a string usando str() o definir json_encoders en Pydantic.
- Usar operaciones bloqueantes en funciones async: Llamar a métodos sincrónicos de pymongo dentro de endpoints async puede degradar el rendimiento. Solución: Usar exclusivamente motor.motor_asyncio para todas las operaciones.
- Falta de validación de esquemas flexibles: En NoSQL, es tentador aceptar cualquier dato, pero esto lleva a inconsistencias. Solución: Usar Pydantic con campos Optional y validaciones personalizadas para mantener calidad.
- No configurar timeouts de conexión: En producción, conexiones infinitas pueden causar bloqueos. Solución: Añadir parámetros como connectTimeoutMS en la URI de MongoDB.
- Ignorar índices para consultas frecuentes: Sin índices, consultas en grandes colecciones son lentas. Solución: Crear índices en campos como email o name usando create_index de manera asíncrona.
Checklist de dominio
- Configurar conexión asíncrona a MongoDB usando variables de entorno.
- Definir modelos Pydantic que mapeen documentos BSON a objetos Python.
- Implementar operaciones CRUD completas (crear, leer, actualizar, eliminar) con manejo de errores.
- Usar agregaciones de MongoDB para consultas complejas, como búsquedas con $match y $group.
- Probar la API con datos reales, verificando respuestas y tiempos de ejecución.
- Optimizar consultas con índices y proyecciones para reducir transferencia de datos.
- Documentar endpoints con ejemplos de solicitud y respuesta en la documentación automática de FastAPI.
Implementar un sistema de blog con FastAPI y MongoDB
En este ejercicio, construirás una API para un blog que permita crear posts, agregar comentarios, y buscar contenido por etiquetas, utilizando MongoDB como base de datos NoSQL.
- Configura el entorno: Crea un proyecto FastAPI, instala motor y pymongo, y configura una conexión asíncrona a una base de datos MongoDB local o en la nube (puedes usar MongoDB Atlas para pruebas).
- Define los modelos: Crea esquemas Pydantic para Post (con campos como title, content, tags, author) y Comment (con text, author, timestamp). Usa tipos Optional para campos como tags que pueden ser flexibles.
- Implementa endpoints:
- POST /posts/ para crear un nuevo post.
- GET /posts/ para listar todos los posts con paginación (usando skip y limit).
- GET /posts/{post_id} para obtener un post específico con sus comentarios anidados.
- POST /posts/{post_id}/comments para agregar un comentario a un post.
- GET /posts/search/?tag= para buscar posts por etiquetas usando operadores de MongoDB como $in.
- Añade características avanzadas: Implementa una agregación para contar comentarios por post y devolverlo en la respuesta, y crea un índice en el campo tags para optimizar búsquedas.
- Prueba la API: Usa herramientas como Postman o curl para verificar que todos los endpoints funcionen correctamente, manejando errores como posts no encontrados con HTTP 404.
- Usa la estructura de documentos anidados en MongoDB para almacenar comentarios dentro de cada post, pero considera la escalabilidad si los comentarios crecen mucho.
- Para la paginación, recuerda que MongoDB usa skip y limit; en producción, considera usar rangos basados en _id para mejor rendimiento.
- En las búsquedas por etiquetas, usa $in en lugar de igualdad exacta para permitir múltiples etiquetas en un solo post.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.