66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
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"),
|
|
) |