En el mundo del desarrollo backend, la escalabilidad se ha convertido en un requisito esencial para cualquier API moderna. Afortunadamente, herramientas como FastAPI y PostgreSQL ofrecen una combinación poderosa de velocidad, simplicidad y robustez que permite crear aplicaciones backend altamente escalables sin complicaciones innecesarias.
En este artÃculo, aprenderás cómo estructurar una API escalable utilizando FastAPI (una de las frameworks más rápidas y modernas para Python) y PostgreSQL, una base de datos relacional open source ampliamente utilizada por su rendimiento y fiabilidad. Todo el contenido está actualizado al ecosistema tecnológico de 2025.
¿Por qué FastAPI y PostgreSQL?
FastAPI ha ganado enorme popularidad desde su lanzamiento gracias a su rendimiento casi comparable a Node.js y Go, su soporte completo para tipado estático con Pydantic, y su documentación automática basada en OpenAPI. A dÃa de hoy, en 2025, se utiliza en startups y grandes empresas por igual.
PostgreSQL, por su parte, es una base de datos madura y extremadamente flexible que se adapta bien a múltiples contextos: desde monolitos hasta microservicios distribuidos, y desde cargas moderadas hasta aplicaciones con millones de usuarios concurrentes.
Juntas, estas dos tecnologÃas forman una base sólida para construir APIs que no solo funcionen bien en desarrollo, sino que puedan escalar en producción sin dolores de cabeza.
Requisitos previos
Antes de comenzar, asegúrate de tener instaladas las siguientes herramientas:
-
Python 3.11 o superior
-
PostgreSQL 15 o superior
-
pip
yvirtualenv
ovenv
para entornos virtuales -
Conocimientos básicos de Python y SQL
Además, usaremos algunas bibliotecas esenciales:
pip install fastapi[all] psycopg[binary] sqlalchemy alembic
Esto incluye:
-
fastapi
: el framework principal -
psycopg
: el driver para PostgreSQL (psycopg3) -
sqlalchemy
: ORM para manejar la base de datos -
alembic
: para migraciones
Estructura del proyecto
Para mantener la API escalable, es buena práctica organizar el código en módulos claros. Una estructura básica puede ser:
app/
??? main.py
??? models/
? ??? user.py
??? schemas/
? ??? user.py
??? crud/
? ??? user.py
??? db/
? ??? session.py
? ??? base.py
??? routers/
? ??? user.py
??? core/
??? config.py
Esta separación permite mantener el código limpio y fácil de mantener, lo que es crucial cuando el proyecto crece.
Conectando con PostgreSQL
En db/session.py
puedes configurar la conexión a PostgreSQL:
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
DATABASE_URL = "postgresql+asyncpg://user:password@localhost/dbname"
engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
Asegúrate de usar asyncpg
como driver para obtener el máximo rendimiento con SQLAlchemy en modo asÃncrono.
Definiendo un modelo con SQLAlchemy
En models/user.py
:
from sqlalchemy import Column, Integer, String
from app.db.base import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
name = Column(String)
En schemas/user.py
defines los esquemas con Pydantic:
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
email: EmailStr
name: str
class UserRead(UserCreate):
id: int
CRUD básico
En crud/user.py
:
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.user import User
from app.schemas.user import UserCreate
async def create_user(db: AsyncSession, user: UserCreate):
new_user = User(**user.dict())
db.add(new_user)
await db.commit()
await db.refresh(new_user)
return new_user
Enrutamiento y lógica de negocio
En routers/user.py
:
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from app.schemas.user import UserCreate, UserRead
from app.crud.user import create_user
from app.db.session import AsyncSessionLocal
router = APIRouter()
async def get_db():
async with AsyncSessionLocal() as session:
yield session
@router.post("/users", response_model=UserRead)
async def create_new_user(user: UserCreate, db: AsyncSession = Depends(get_db)):
return await create_user(db, user)
Y finalmente en main.py
:
from fastapi import FastAPI
from app.routers import user
app = FastAPI()
app.include_router(user.router, prefix="/api")
Al ejecutar uvicorn app.main:app --reload
, tu API estará disponible en http://localhost:8000/api/users
y con documentación automática en /docs
.
Escalabilidad: mejores prácticas
Para que esta arquitectura escale correctamente en producción, ten en cuenta:
-
Usa Uvicorn con Gunicorn:
gunicorn -k uvicorn.workers.UvicornWorker app.main:app --workers 4
-
Implementa caching (por ejemplo con Redis) si necesitas reducir consultas a la base de datos.
-
Controla el pool de conexiones para no saturar PostgreSQL con múltiples instancias.
-
Divide tu lógica en microservicios si crece demasiado.
-
Monitoriza con Prometheus o herramientas APM como Sentry o Datadog.
-
Usa migraciones de base de datos con Alembic para evitar problemas al escalar o desplegar.
Consideraciones para producción en 2025
En entornos modernos cloud-native (Docker, Kubernetes, serverless, etc.), es recomendable que tu API:
-
Sea completamente asÃncrona para aprovechar mejor los recursos.
-
Utilice un ORM liviano si el rendimiento es crÃtico (ej. SQLModel o incluso queries puras con
asyncpg
). -
Implemente observabilidad desde el inicio: métricas, logs estructurados y alertas.
-
Evite sobreingenierÃa: empieza simple y escala conforme lo necesites.
Conclusión
FastAPI y PostgreSQL son una pareja ideal para construir APIs modernas y escalables. Al usar una arquitectura modular, aprovechar el rendimiento asÃncrono y seguir buenas prácticas de desarrollo, estarás en una excelente posición para desplegar servicios robustos que puedan crecer contigo.
Si estás buscando una tecnologÃa para tu próximo proyecto en 2025, FastAPI con PostgreSQL sigue siendo una de las combinaciones más poderosas y productivas en el ecosistema Python.