InfraNotes API Gateway · v2
Welcome
Select a document from the sidebar to read it.
🚀 Production Deployment Guide
Overview
This guide covers deploying the InfraNotes API Gateway in production environments with proper security, scalability, and observability configurations.
📋 Current vs Production Route Configuration
Current Development Setup (Environment Variables)
# Docker Compose approach - NOT recommended for production
- INFRANOTES_ROUTES_0_PATH=/api/auth/*
- INFRANOTES_ROUTES_0_BACKEND=http://infranotes-main:8080
- INFRANOTES_ROUTES_0_METHODS=GET,POST,PUT,DELETE,PATCH
- INFRANOTES_ROUTES_0_AUTH_REQUIRED=false
Production Setup (Configuration Files)
# Use configs/config.production.yaml instead
routes:
- path: "/api/auth/*"
backend: "https://auth.infranotes.production"
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"]
auth_required: false
rate_limit: 100
circuit_breaker: "auth-service"
health_check_enabled: true
load_balancer_enabled: true
✅ Gateway Route Capability Verification
Your InfraNotes API Gateway CAN handle any route configuration you define in the config file:
Route Matching System
- ✅ Wildcard Path Support:
/api/auth/*matches/api/auth/login,/api/auth/register, etc. - ✅ Exact Path Matching:
/healthmatches exactly/health - ✅ HTTP Method Filtering: Supports
GET,POST,PUT,DELETE,PATCH, etc. - ✅ Dynamic Backend Resolution: Routes to any backend URL/service
- ✅ Per-Route Configuration: Individual auth, rate limiting, circuit breaker settings
Route Processing Flow
// 1. Route Discovery (internal/router/router.go:350-420)
for _, route := range cfg.Routes {
// Register each route with Gin router
r.GET(ginPath, proxyHandler.Handle)
r.POST(ginPath, proxyHandler.Handle)
// ... for all HTTP methods
}
// 2. Route Matching (internal/proxy/proxy.go:398-435)
func (h *Handler) matchesRoute(route *config.Route, method, path string) bool {
// Check HTTP method match
// Check path pattern (wildcard support)
// Return matching route
}
// 3. Request Forwarding (internal/proxy/proxy.go:252-397)
func (h *Handler) forwardRequest(c *gin.Context, route *config.Route, backendURL string) {
// Apply rate limiting, circuit breakers, health checks
// Forward to configured backend
}
🏗️ Production Architecture
1. Infrastructure Components
# Production stack
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Load Balancer │ │ API Gateway │ │ Backend Apps │
│ (ALB/NGINX) │───▶│ (Multiple) │───▶│ (Auto-scaling) │
│ SSL/TLS │ │ Rate Limiting │ │ Health Checks │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┢─────────────────┐
│ DNS/Route53 │ │ Redis Cluster │ │ NATS Cluster │
│ SSL Certs │ │ Distributed │ │ Service Mesh │
│ Health Checks │ │ Rate Limiting │ │ Auth Provider │
└─────────────────┘ └──────────────────┘ └─────────────────┘
2. Deployment Options
Option A: Kubernetes (Recommended)
# k8s/gateway-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: infranotes-gateway
namespace: infranotes
spec:
replicas: 3
selector:
matchLabels:
app: infranotes-gateway
template:
metadata:
labels:
app: infranotes-gateway
spec:
containers:
- name: gateway
image: infranotes/gateway:1.0.0
ports:
- containerPort: 8080
env:
- name: CONFIG_FILE
value: "/etc/config/config.production.yaml"
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
- name: secrets
mountPath: /etc/secrets
readOnly: true
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: gateway-config
- name: secrets
secret:
secretName: gateway-secrets
Option B: Docker Swarm
# docker-stack.yml
version: '3.8'
services:
infranotes-gateway:
image: infranotes/gateway:1.0.0
deploy:
replicas: 3
placement:
constraints:
- node.role == worker
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
ports:
- "8080:8080"
configs:
- source: gateway_config
target: /app/configs/config.production.yaml
secrets:
- source: redis_password
target: /run/secrets/redis_password
networks:
- infranotes_network
🔧 Production Configuration
1. Secrets Management
# Use environment variable substitution
redis:
address: "redis.infranotes.production:6379"
password: "${REDIS_PASSWORD}" # From secrets manager
# Or use external secrets
nats:
url: "${NATS_URL}"
auth_token: "${NATS_AUTH_TOKEN}"
datadog:
api_key: "${DD_API_KEY}"
app_key: "${DD_APP_KEY}"
2. Service Discovery Integration
# Production service discovery
service_discovery:
enabled: true
nats_subject: "service.discovery"
health_subject: "service.health"
service_ttl: 300s
health_check_interval: 30s
require_metadata: ["version", "zone", "region"]
allowed_regions: ["us-east-1", "us-west-2", "eu-west-1"]
allowed_zones: ["us-east-1a", "us-east-1b", "us-west-2a"]
# Routes with service discovery
routes:
- path: "/api/auth/*"
backend: "service://auth-service" # Service discovery
methods: ["GET", "POST", "PUT", "DELETE"]
auth_required: false
load_balancer_enabled: true
health_check_enabled: true
3. SSL/TLS Configuration
# Use external load balancer for SSL termination
server:
port: 8080 # Internal HTTP only
read_timeout: 30s
write_timeout: 30s
# Or configure internal TLS
server:
port: 8443
tls_enabled: true
cert_file: "/etc/ssl/certs/gateway.crt"
key_file: "/etc/ssl/private/gateway.key"
security:
headers:
strict_transport_security: "max-age=63072000; includeSubDomains; preload"
content_security_policy: "default-src 'self'"
📈 Production Monitoring
1. Observability Stack
# Production observability
observability:
metrics:
enabled: true
collection_interval: 15s
infrastructure_metrics: true
business_metrics: true
slos:
- name: "availability"
target: 99.95 # 99.95% uptime
time_window: "30d"
- name: "latency_p95"
target: 50 # 50ms P95 latency
time_window: "24h"
alerts:
error_rate_threshold: 0.005 # 0.5%
latency_p95_threshold: 100 # 100ms
availability_threshold: 99.9
# DataDog integration
datadog:
service_name: "infranotes-gateway"
environment: "production"
tracing_enabled: true
sampling_rate: 0.1 # 10% sampling
profiling_enabled: true
runtime_metrics_enabled: true
agent_url: "http://datadog-agent:8126"
2. Alerting Rules
# Alert conditions
alerts:
- name: "High Error Rate"
condition: "error_rate > 1%"
duration: "5m"
severity: "critical"
- name: "High Latency"
condition: "latency_p95 > 200ms"
duration: "5m"
severity: "warning"
- name: "Circuit Breaker Open"
condition: "circuit_breaker_state == 'open'"
duration: "1m"
severity: "critical"
🛡️ Security Configuration
1. Production Security
security:
max_request_size: "10MB"
max_response_size: "50MB"
ip_filtering:
enabled: true
whitelist:
- "10.0.0.0/8" # Internal networks
- "172.16.0.0/12" # Private networks
- "192.168.0.0/16" # Local networks
auto_block:
enabled: true
threshold: 100
duration: 3600s
ddos_protection:
enabled: true
connection_limit: 10000
requests_per_second: 1000
burst_size: 2000
headers:
strict_transport_security: "max-age=63072000; includeSubDomains; preload"
content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-inline'"
x_frame_options: "DENY"
x_content_type_options: "nosniff"
2. Rate Limiting Strategy
rate_limiting:
enabled: true
rules:
# Critical endpoints (authentication)
- name: "auth-endpoints"
paths: ["/api/auth/login", "/api/auth/register"]
methods: ["POST"]
priority: 1
user_config:
algorithm: "sliding_window"
limit: 5 # 5 attempts per user
window: 300s # per 5 minutes
ip_config:
algorithm: "sliding_window"
limit: 20 # 20 attempts per IP
window: 300s # per 5 minutes
global_config:
algorithm: "token_bucket"
limit: 1000 # 1000 global attempts
window: 3600s # per hour
burst: 100
# API endpoints
- name: "api-endpoints"
paths: ["/api/*"]
methods: ["GET", "POST", "PUT", "DELETE"]
priority: 10
user_config:
algorithm: "token_bucket"
limit: 1000 # 1000 requests per user
window: 3600s # per hour
burst: 50
ip_config:
algorithm: "sliding_window"
limit: 2000 # 2000 requests per IP
window: 3600s # per hour
🚀 Deployment Process
1. Pre-deployment Checklist
- Configuration validated (
go run cmd/gateway/main.go --validate-config) - Security scan completed
- Load testing performed
- Monitoring/alerting configured
- Rollback plan prepared
- DNS/Load balancer updated
2. Blue-Green Deployment
#!/bin/bash
# deploy.sh
# 1. Deploy to green environment
kubectl apply -f k8s/gateway-deployment.yaml --namespace=infranotes-green
# 2. Wait for health checks
kubectl wait --for=condition=ready pod -l app=infranotes-gateway -n infranotes-green --timeout=300s
# 3. Run smoke tests
curl -f https://api-green.infranotes.production/health || exit 1
# 4. Switch traffic
kubectl patch service infranotes-gateway -n infranotes -p '{"spec":{"selector":{"version":"green"}}}'
# 5. Monitor for issues
sleep 60
# 6. Scale down blue environment
kubectl scale deployment infranotes-gateway-blue --replicas=0 -n infranotes
3. Rolling Updates
# Kubernetes rolling update strategy
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
spec:
containers:
- name: gateway
image: infranotes/gateway:1.0.1 # New version
📊 Performance Optimization
1. Resource Allocation
# Kubernetes resources
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
# JVM/Go optimization
environment:
- GOMAXPROCS=4
- GOMEMLIMIT=1GiB
- GOGC=100
2. Caching Strategy
caching:
# L1 Cache (In-memory)
l1_cache_enabled: true
l1_cache_size: 10000
l1_cache_ttl: 300s
# Redis (L2 Cache)
address: "redis-cluster.infranotes.production:6379"
pool_size: 100
default_ttl: 3600s
compression_enabled: true
# Performance tuning
pipeline_enabled: true
pipeline_size: 100
batch_size: 50
🔍 Health Checks & Circuit Breakers
1. Health Check Configuration
health_checks:
enabled: true
interval: 30s
timeout: 5s
failure_threshold: 3
success_threshold: 2
path: "/health"
expected_status_codes: [200]
max_response_time: 5s
2. Circuit Breaker Strategy
circuit_breakers:
enabled: true
services:
- name: "auth-service"
failure_threshold: 5 # Trip after 5 failures
success_threshold: 2 # Reset after 2 successes
timeout_duration: 30s # Stay open for 30s
slow_call_threshold: 5s # Consider >5s as slow
- name: "main-app"
failure_threshold: 3
timeout_duration: 60s
max_half_open_requests: 2
🎯 Route Examples
Your gateway supports these production route patterns:
routes:
# Microservice routing
- path: "/api/auth/*"
backend: "https://auth-service.infranotes.internal"
methods: ["GET", "POST", "PUT", "DELETE"]
auth_required: false
rate_limit: 100
circuit_breaker: "auth-service"
# API versioning
- path: "/api/v1/expenses/*"
backend: "https://expenses-v1.infranotes.internal"
methods: ["GET", "POST", "PUT", "DELETE"]
auth_required: true
rate_limit: 200
- path: "/api/v2/expenses/*"
backend: "https://expenses-v2.infranotes.internal"
methods: ["GET", "POST", "PUT", "DELETE"]
auth_required: true
rate_limit: 200
# External service integration
- path: "/api/payment/*"
backend: "https://payment-gateway.stripe.com/api"
methods: ["POST"]
auth_required: true
rate_limit: 50
# Static content
- path: "/docs/*"
backend: "https://cdn.infranotes.com"
methods: ["GET"]
auth_required: false
rate_limit: 1000
# Health and monitoring
- path: "/health"
backend: "internal://health"
methods: ["GET"]
auth_required: false
rate_limit: 10000
# Metrics (internal only)
- path: "/metrics"
backend: "internal://metrics"
methods: ["GET"]
auth_required: false
rate_limit: 100
✅ Conclusion
Your InfraNotes API Gateway is fully capable of handling any route configuration you define. The system provides:
- ✅ Dynamic Route Configuration: Add/modify routes via config files
- ✅ Wildcard Path Support:
/api/service/*patterns - ✅ HTTP Method Filtering: Per-route method restrictions
- ✅ Backend Flexibility: Route to any HTTP/HTTPS backend
- ✅ Production Features: Rate limiting, circuit breakers, health checks
- ✅ Observability: Metrics, tracing, logging for all routes
Production Ready: Use the configs/config.production.yaml approach instead of environment variables for better maintainability, security, and scalability.