import httpx from fastapi import FastAPI, Request, Response app = FastAPI() SERVICES = { "users": "http://user-service:8000", "products": "http://catalog-service:8000", "orders": "http://order-service:8000", "notifications": "http://notif-service:8000", } TIMEOUT = 5.0 @app.get("/health") def health(): return {"status": "ok", "service": "api-gateway"} @app.api_route("/{full_path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"]) async def gateway(full_path: str, request: Request): # Extraire le nom du service depuis le début du chemin # ex: "users/1" → service="users", "orders" → service="orders" parts = full_path.split("/", 1) service_key = parts[0] base_url = SERVICES.get(service_key) if not base_url: return Response( content=f'{{"detail": "Service \'{service_key}\' inconnu"}}', status_code=404, media_type="application/json", ) target_url = f"{base_url}/{full_path}" if request.url.query: target_url += f"?{request.url.query}" body = await request.body() async with httpx.AsyncClient() as client: try: response = await client.request( method=request.method, url=target_url, content=body, headers={"Content-Type": request.headers.get("Content-Type", "application/json")}, timeout=TIMEOUT, ) except httpx.TimeoutException: return Response( content='{"detail": "Service timeout"}', status_code=504, media_type="application/json", ) except Exception as e: return Response( content=f'{{"detail": "Gateway error: {str(e)}"}}', status_code=502, media_type="application/json", ) return Response( content=response.content, status_code=response.status_code, media_type=response.headers.get("content-type"), )