Skip to main content
Gateway Documentation

This documents the API gateway architecture and behavior. These are not callable endpoints — they describe how the gateway processes requests.

API Gateway Architecture

The Olympus Cloud API Gateway is a high-performance Go service that provides centralized routing, authentication, and traffic management for all platform APIs.

Overview

The Gateway handles 95+ route handlers across all services:

ServiceRoutesProtocol
Auth Service15+REST
Platform Service20+REST + GraphQL
Commerce Service30+REST
AI/ML Service15+REST + WebSocket
Integrations15+REST + Webhooks

Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│ API GATEWAY (Go) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────────────────────────────────────────────────┐ │
│ │ Load │ │ MIDDLEWARE CHAIN │ │
│ │Balancer │──▶│ [CORS] → [Rate Limit] → [Auth] → [Tenant] → [Log] │ │
│ └─────────┘ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ROUTE HANDLERS │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ /auth/* │ /platform/* │ /commerce/* │ /ai/* │ │
│ │ /graphql │ /ws/* │ /webhooks/* │ /integrations/* │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ SERVICE PROXY LAYER │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ [Circuit Breaker] → [Retry] → [Timeout] → [Service Call] │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
└────────────────────────────────────────┼─────────────────────────────────┘

┌─────────────────────────────┼─────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Auth Service│ │ Platform │ │ Commerce │
│ (Rust) │ │ (Rust) │ │ (Rust) │
└─────────────┘ └─────────────┘ └─────────────┘

Request Flow

1. Ingress

Client Request


┌─────────────┐
│ Cloud Run │ ← TLS termination
│ Load Balancer│ ← Health checks
└─────────────┘


┌─────────────┐
│ API Gateway │ ← Single entry point
└─────────────┘

2. Middleware Chain

Each request passes through middleware in order:

// Middleware execution order
router.Use(
middleware.RequestID(), // Trace ID injection
middleware.CORS(corsConfig), // CORS headers
middleware.RateLimit(config), // Global rate limiting
middleware.Logger(logger), // Request logging
middleware.Recovery(), // Panic recovery
)

// Protected routes add auth middleware
protected.Use(
middleware.JWTAuth(jwtConfig), // Token validation
middleware.TenantContext(), // Tenant extraction
middleware.TenantRateLimit(), // Per-tenant limits
middleware.Permissions(), // RBAC enforcement
)

3. Route Matching

Routes are matched by path and method:

Path PatternServiceHandler
/api/v1/auth/*Auth ServiceProxy
/api/v1/platform/*Platform ServiceProxy
/api/v1/commerce/*Commerce ServiceProxy
/api/v1/ai/*AI/ML ServiceProxy
/graphqlPlatform ServiceGraphQL
/ws/*GatewayWebSocket

4. Service Proxy

The gateway proxies requests to backend services:

// Service proxy with resilience patterns
proxy := &ServiceProxy{
client: httpClient,
circuitBreaker: circuitBreaker,
retryPolicy: retryPolicy,
timeout: 30 * time.Second,
}

Middleware Components

CORS Middleware

corsConfig := middleware.CORSConfig{
AllowOrigins: []string{
"https://app.olympuscloud.ai",
"https://admin.olympuscloud.ai",
"https://pos.restaurantrevolution.ai",
},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"},
AllowHeaders: []string{
"Authorization",
"Content-Type",
"X-Request-ID",
"X-Tenant-ID",
},
ExposeHeaders: []string{"X-Rate-Limit-*"},
AllowCredentials: true,
MaxAge: 3600,
}

JWT Authentication

jwtConfig := middleware.JWTConfig{
SigningMethod: jwt.SigningMethodRS256,
KeyFunc: jwksKeyFunc, // JWKS key lookup
TokenLookup: "header:Authorization,query:token",
ContextKey: "user",
Claims: &CustomClaims{},
Skipper: publicPathSkipper, // Skip for public routes
}

Tenant Context

Extracts tenant information from JWT or API key:

func TenantContext() gin.HandlerFunc {
return func(c *gin.Context) {
// Extract from JWT claims
if claims, ok := c.Get("user"); ok {
tenantID := claims.(*CustomClaims).TenantID
c.Set("tenant_id", tenantID)
}

// Or from API key
if apiKey := c.GetHeader("X-API-Key"); apiKey != "" {
tenant := lookupTenantByAPIKey(apiKey)
c.Set("tenant_id", tenant.ID)
c.Set("tenant_tier", tenant.Tier)
}

c.Next()
}
}

Service Discovery

Cloud Run Services

Services are discovered via environment configuration:

type ServiceConfig struct {
AuthService string `env:"AUTH_SERVICE_URL"`
PlatformService string `env:"PLATFORM_SERVICE_URL"`
CommerceService string `env:"COMMERCE_SERVICE_URL"`
AIService string `env:"AI_SERVICE_URL"`
}

Health Checks

The gateway performs health checks on backend services:

// Health check configuration
healthCheck := &HealthCheck{
Interval: 10 * time.Second,
Timeout: 5 * time.Second,
Path: "/healthz",
Threshold: 3, // Failures before unhealthy
}

Endpoints:

EndpointDescription
GET /healthzGateway liveness
GET /healthGateway + dependencies
GET /readyGateway readiness

Resilience Patterns

Circuit Breaker

Prevents cascade failures:

circuitBreaker := &CircuitBreaker{
MaxFailures: 5,
ResetTimeout: 30 * time.Second,
HalfOpenMax: 3,
OnStateChange: logStateChange,
}

// States: Closed → Open → Half-Open → Closed
StateBehavior
ClosedNormal operation, requests pass through
OpenRequests fail fast, returns 503
Half-OpenLimited requests to test recovery

Retry Policy

Automatic retries for transient failures:

retryPolicy := &RetryPolicy{
MaxRetries: 3,
InitialDelay: 100 * time.Millisecond,
MaxDelay: 2 * time.Second,
Multiplier: 2.0,
RetryableErrors: []int{502, 503, 504},
}

Timeouts

Layer-specific timeouts:

LayerTimeoutPurpose
Client connection10sConnection establishment
Request30sTotal request time
Idle60sKeep-alive timeout
Backend call25sService proxy timeout

Load Balancing

Cloud Run Auto-scaling

# Cloud Run configuration
spec:
containerConcurrency: 100
timeoutSeconds: 300
template:
metadata:
annotations:
autoscaling.knative.dev/minScale: "2"
autoscaling.knative.dev/maxScale: "100"
spec:
resources:
limits:
cpu: "2"
memory: "1Gi"

Request Distribution

  • Round-robin: Default distribution
  • Least connections: For long-running requests
  • Session affinity: Optional for stateful endpoints

WebSocket Handling

Connection Lifecycle

Client                    Gateway                    Service
│ │ │
│──── WS Upgrade ────────▶│ │
│ │──── Authenticate ───────▶│
│ │◀──── Auth Result ────────│
│◀─── Connection OK ──────│ │
│ │ │
│──── Subscribe ─────────▶│ │
│ │──── Register Sub ───────▶│
│ │ │
│◀──── Events ────────────│◀──── Pub/Sub ───────────│
│ │ │

Subscription Management

type WebSocketManager struct {
connections map[string]*Connection
subscriptions map[string][]string // topic → connection IDs
pubsub *redis.Client
}

// Subscribe to topics
func (m *WebSocketManager) Subscribe(connID string, topics []string) {
for _, topic := range topics {
m.subscriptions[topic] = append(m.subscriptions[topic], connID)
m.pubsub.Subscribe(ctx, topic)
}
}

Integration Handlers

Stripe Connect

// Stripe webhook handling
router.POST("/webhooks/stripe", stripeWebhookHandler)
router.POST("/integrations/stripe/connect", stripeConnectHandler)
router.GET("/integrations/stripe/account/:id", stripeAccountHandler)

Delivery Platforms

// Delivery integration endpoints
router.POST("/webhooks/doordash", doordashWebhookHandler)
router.POST("/webhooks/ubereats", ubereatsWebhookHandler)
router.POST("/webhooks/grubhub", grubhubWebhookHandler)

Accounting Systems

// Accounting integration endpoints
router.POST("/integrations/quickbooks/connect", quickbooksConnectHandler)
router.POST("/integrations/xero/connect", xeroConnectHandler)
router.POST("/webhooks/quickbooks", quickbooksWebhookHandler)

ACP Integration

The gateway integrates with the AI Control Plane (ACP):

// ACP endpoints
router.GET("/api/v1/acp/agents", acpListAgents)
router.GET("/api/v1/acp/agents/:id/status", acpAgentStatus)
router.POST("/api/v1/acp/agents/:id/approve", acpApproveAction)
router.POST("/api/v1/acp/agents/:id/reject", acpRejectAction)
router.GET("/api/v1/acp/costs", acpCostTracking)

Agent Monitoring

  • Real-time agent status
  • Action approval workflows (HITL)
  • Cost tracking per agent/tenant
  • Safety control enforcement

Observability

Metrics

// Prometheus metrics
var (
requestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "gateway_requests_total",
Help: "Total HTTP requests",
},
[]string{"method", "path", "status"},
)

requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "gateway_request_duration_seconds",
Help: "Request duration in seconds",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "path"},
)
)

Distributed Tracing

// OpenTelemetry tracing
tracer := otel.Tracer("api-gateway")

func TracingMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
ctx, span := tracer.Start(c.Request.Context(), c.FullPath())
defer span.End()

span.SetAttributes(
attribute.String("http.method", c.Request.Method),
attribute.String("tenant.id", c.GetString("tenant_id")),
)

c.Request = c.Request.WithContext(ctx)
c.Next()

span.SetAttributes(
attribute.Int("http.status_code", c.Writer.Status()),
)
}
}

Structured Logging

// Structured JSON logging
logger := zerolog.New(os.Stdout).With().
Str("service", "api-gateway").
Logger()

// Request logging
logger.Info().
Str("request_id", requestID).
Str("method", method).
Str("path", path).
Str("tenant_id", tenantID).
Int("status", status).
Dur("duration", duration).
Msg("request completed")

Configuration

Environment Variables

VariableDescriptionDefault
PORTListen port8080
LOG_LEVELLogging levelinfo
AUTH_SERVICE_URLAuth service URL-
PLATFORM_SERVICE_URLPlatform service URL-
COMMERCE_SERVICE_URLCommerce service URL-
AI_SERVICE_URLAI service URL-
REDIS_URLRedis connection (rediss:// for Memorystore TLS)-
JWT_JWKS_URLJWKS endpoint-

Feature Flags

// Runtime configuration via feature flags
if featureEnabled("new_auth_flow", tenantID) {
// Use new authentication flow
}

Security

TLS Configuration

  • TLS 1.2+ required
  • Strong cipher suites only
  • Certificate rotation via Cloud Run

Request Validation

  • Input sanitization
  • Content-Type enforcement
  • Request size limits (10MB default)
  • SQL injection prevention

Audit Logging

All sensitive operations are audit-logged:

  • Authentication events
  • Authorization failures
  • Rate limit violations
  • Admin operations