Expo Demo — GCP Architecture
BFF + Backend on Cloud Run, behind a Global HTTPS Load Balancer. expo.uat.ebitdao.ai
How traffic flows
Cloudflare DNS (grey cloud) — same GLB IP for both domains
expo.uat.ebitdao.ai → 34.x.x.x (GCP Global HTTPS LB)
api.uat.ebitdao.ai → 34.x.x.x (same LB)
LB URL Map
expo.uat.ebitdao.ai /*
→ Cloud Run: expo-fe (this page + BFF)
Server-side: BACKEND_URL → expo-backend (never sent to browser)
/api/public/hello ✓ public endpoint
/api/private/secret ✓ private endpoint (only BFF can reach this)
api.uat.ebitdao.ai /expo/api/public/*
→ Cloud Run: expo-backend (GLB strips /expo prefix → /api/public/*)
api.uat.ebitdao.ai /expo/api/private/*
→ NO ROUTE in URL map → 404 from LBPublic endpoint
publicBFF → backend /api/public/hello
Also exposed directly: expo.uat.ebitdao.ai/api/public/hello
{
"endpoint": "public",
"message": "Hello from the public endpoint",
"note": "Routed via GLB URL map — accessible at expo.uat.ebitdao.ai/api/public/hello",
"timestamp": "2026-07-01T04:44:54.548127+00:00"
}Private endpoint
privateBFF → backend /api/private/secret
NOT in GLB URL map — /api/private/secret returns 404 from the LB
{
"endpoint": "private",
"message": "Secret data — not exposed via GLB URL map",
"secret_value": "s3cr3t-42",
"note": "Only the BFF (server-side) can reach this; the GLB has no route for /api/private/*",
"timestamp": "2026-07-01T04:44:54.548434+00:00"
}Test the routing
| Full URL | Routed to | Expected result |
|---|---|---|
expo.uat.ebitdao.ai/ | expo-fe (this page) | ✓ SSR — BFF fetches both endpoints server-side |
expo.uat.ebitdao.ai/api/from-public | expo-fe BFF route | ✓ JSON — proxies to backend public endpoint |
expo.uat.ebitdao.ai/api/from-private | expo-fe BFF route | ✓ JSON — proxies to backend private endpoint (backend URL stays hidden) |
api.uat.ebitdao.ai/expo/api/public/hello | expo-backend (via GLB, prefix rewrite) | ✓ Direct JSON from backend |
api.uat.ebitdao.ai/expo/api/private/secret | No URL map entry | ✗ 404 from LB — private path not in URL map |