python --version
pip install fastapi uvicorn httpx
Implement a gateway layer with routing, rate limiting headers, request ID injection, and upstream forwarding.
1 import uuid 2 import time 3 import httpx 4 from fastapi import FastAPI, Request, Response 5 from fastapi.responses import JSONResponse 6 7 app = FastAPI(title="API Gateway") 8 9 UPSTREAM_BASE = "https://httpbin.org" # Replace with your backend 10 11 @app.middleware("http") 12 async def add_request_headers(request: Request, call_next): 13 request_id = str(uuid.uuid4()) 14 start = time.monotonic() 15 response = await call_next(request) 16 duration_ms = round((time.monotonic() - start) * 1000, 2) 17 response.headers["X-Request-ID"] = request_id 18 response.headers["X-Duration-Ms"] = str(duration_ms) 19 return response 20 21 @app.api_route("/api/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"]) 22 async def proxy(request: Request, path: str): 23 upstream_url = f"{UPSTREAM_BASE}/{path}" 24 body = await request.body() 25 26 async with httpx.AsyncClient() as client: 27 upstream_resp = await client.request( 28 method=request.method, 29 url=upstream_url, 30 headers={k: v for k, v in request.headers.items() if k.lower() != "host"}, 31 content=body, 32 params=dict(request.query_params), 33 ) 34 35 return Response( 36 content=upstream_resp.content, 37 status_code=upstream_resp.status_code, 38 headers=dict(upstream_resp.headers), 39 media_type=upstream_resp.headers.get("content-type"), 40 ) 41 42 @app.get("/health") 43 async def health(): 44 try: 45 async with httpx.AsyncClient(timeout=3) as client: 46 resp = await client.get(f"{UPSTREAM_BASE}/status/200") 47 return {"status": "healthy", "upstream": resp.status_code} 48 except Exception as e: 49 return JSONResponse({"status": "unhealthy", "error": str(e)}, status_code=503) 50
Sign in to share your feedback and join the discussion.