Volver a proyectos
Backend
1 min de lectura

API Gateway y Orquestación

Por Jeferson Heredia
13 de marzo de 2025
Python
FastAPI
Microservicios
API Gateway
API Gateway y Orquestación

Descripción

Este servicio de API Gateway actúa como punto de entrada unificado para múltiples microservicios, gestionando el enrutamiento, la autenticación, la autorización y la transformación de solicitudes.

Desarrollado con Python y FastAPI, el gateway implementa patrones avanzados como Circuit Breaker, Rate Limiting y Load Balancing para mejorar la resiliencia y el rendimiento del sistema. La arquitectura está diseñada para ser altamente disponible y escalable, permitiendo manejar grandes volúmenes de tráfico.

El sistema incluye capacidades avanzadas de observabilidad, con integración de trazas distribuidas, métricas detalladas y logs estructurados que facilitan el diagnóstico y la resolución de problemas. Además, implementé un sistema de caché inteligente que reduce la latencia y la carga en los servicios backend.

Tecnologías Utilizadas

Python

Lenguaje principal para el desarrollo del gateway

FastAPI

Framework de alto rendimiento para APIs

Redis

Almacenamiento en caché y gestión de rate limiting

Prometheus

Monitoreo y alertas

Jaeger

Trazas distribuidas para observabilidad

Docker

Contenedorización para despliegue consistente

Desafíos

Alta disponibilidad

Garantizar que el gateway nunca se convierta en un punto único de fallo para todo el sistema.

Latencia mínima

Mantener la latencia adicional introducida por el gateway en niveles imperceptibles para los usuarios.

Seguridad robusta

Implementar múltiples capas de seguridad sin comprometer el rendimiento ni la experiencia de usuario.

Soluciones

Arquitectura sin estado

Diseñé el gateway como un servicio sin estado que puede escalar horizontalmente sin problemas de sincronización.

Optimización de rendimiento

Utilicé Cython para optimizar componentes críticos y ASGI para manejar conexiones de manera eficiente.

Seguridad en capas

Implementé un sistema de seguridad en capas con autenticación JWT, HMAC para integridad y cifrado TLS para confidencialidad.

Galería

Dashboard de monitoreo del gateway en tiempo real

Dashboard de monitoreo del gateway en tiempo real

Visualización del flujo de solicitudes a través del gateway

Visualización del flujo de solicitudes a través del gateway

Diagrama de las capas de seguridad implementadas

Diagrama de las capas de seguridad implementadas

Ejemplo de Código

user_manager.py

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from typing import List, Optional
import jwt
from datetime import datetime, timedelta
import asyncio
import logging

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Initialize FastAPI app
app = FastAPI(title="API Gateway Service")

# Security configuration
SECRET_KEY = "your-secret-key"  # In production, use environment variable
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# Models
class ServiceRequest(BaseModel):
    service_name: str
    endpoint: str
    method: str = "GET"
    payload: Optional[dict] = None
    
class ServiceResponse(BaseModel):
    status_code: int
    data: dict
    
class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None
    
class UserInDB(User):
    hashed_password: str
    
class Token(BaseModel):
    access_token: str
    token_type: str
    
# Mock database
fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    }
}

# OAuth2 scheme
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# Helper functions
def verify_password(plain_password, hashed_password):
    # In production, use proper password hashing
    return plain_password + "notreallyhashed" == hashed_password

def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)
    
def authenticate_user(fake_db, username: str, password: str):
    user = get_user(fake_db, username)
    if not user:
        return False
    if not verify_password(password, user.hashed_password):
        return False
    return user
    
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt
    
async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except jwt.PyJWTError:
        raise credentials_exception
    user = get_user(fake_users_db, username=username)
    if user is None:
        raise credentials_exception
    return user
    
async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user

# Routes
@app.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

@app.get("/users/me", response_model=User)
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

@app.post("/gateway", response_model=ServiceResponse)
async def gateway_request(
    request: ServiceRequest,
    current_user: User = Depends(get_current_active_user)
):
    """
    Gateway endpoint that routes requests to appropriate microservices
    """
    logger.info(f"Received request for service: {request.service_name}")
    
    # In a real implementation, this would route to actual services
    # For demo purposes, we'll just return a mock response
    
    # Simulate some processing time
    await asyncio.sleep(0.5)
    
    # Return mock response
    return ServiceResponse(
        status_code=200,
        data={
            "message": f"Request to {request.service_name} processed successfully",
            "endpoint": request.endpoint,
            "method": request.method,
            "timestamp": datetime.now().isoformat()
        }
    )

@app.get("/health")
async def health_check():
    """
    Health check endpoint for the API Gateway
    """
    return {"status": "healthy", "timestamp": datetime.now().isoformat()}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Compartir

Habilidades Python

Python Core
Data Analysis
Web Frameworks
Machine Learning
Testing

¿Interesado en un proyecto similar?

Si estás buscando implementar una solución en Python o tienes un proyecto en mente que requiera habilidades de desarrollo similares, no dudes en contactarme para discutir cómo puedo ayudarte.

Contactar