API Gateway Setup (Kong) for Web Application
Kong is the most widely-used open-source API Gateway, built on nginx/OpenResty. It handles authentication, rate limiting, request transformation, monitoring, and routing for microservices architectures.
Kong Architecture
Kong operates as a proxy: all client requests pass through Kong, which applies plugins and forwards traffic to upstream services. Configuration is stored in PostgreSQL or in DB-less mode via YAML.
Client → Kong Gateway → Plugins (auth, rate limit, log) → Upstream Service
Installing Kong with PostgreSQL
# Docker Compose
version: '3.8'
services:
kong-db:
image: postgres:15
environment:
POSTGRES_DB: kong
POSTGRES_USER: kong
POSTGRES_PASSWORD: kong_password
kong-migration:
image: kong:3.5
command: kong migrations bootstrap
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-db
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong_password
depends_on: [kong-db]
kong:
image: kong:3.5
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-db
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong_password
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: 0.0.0.0:8001
KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl
ports:
- "8000:8000" # HTTP proxy
- "8443:8443" # HTTPS proxy
- "8001:8001" # Admin API (restrict external access!)
depends_on: [kong-migration]
Configuring Services and Routes
# Create upstream service
curl -X POST http://localhost:8001/services \
-d name=users-api \
-d url=http://users-service:3000
# Create route
curl -X POST http://localhost:8001/services/users-api/routes \
-d 'paths[]=/api/v1/users' \
-d 'methods[]=GET' \
-d 'methods[]=POST' \
-d strip_path=false
# Test
curl http://localhost:8000/api/v1/users
Declarative Configuration (DB-less Mode)
# kong.yml
_format_version: "3.0"
services:
- name: users-api
url: http://users-service:3000
routes:
- name: users-route
paths: [/api/v1/users]
strip_path: false
plugins:
- name: rate-limiting
config:
minute: 60
policy: local
- name: jwt
config:
secret_is_base64: false
- name: products-api
url: http://products-service:3001
routes:
- name: products-route
paths: [/api/v1/products]
plugins:
- name: key-auth
Key Plugins
JWT Authentication
# Enable JWT plugin on service
curl -X POST http://localhost:8001/services/users-api/plugins \
-d name=jwt
# Create consumer
curl -X POST http://localhost:8001/consumers \
-d username=mobile-app
# Create JWT credentials
curl -X POST http://localhost:8001/consumers/mobile-app/jwt \
-d algorithm=RS256 \
-d rsa_public_key="$(cat public.pem)"
Rate Limiting with Redis
curl -X POST http://localhost:8001/plugins \
-d name=rate-limiting \
-d config.minute=100 \
-d config.hour=5000 \
-d config.policy=redis \
-d config.redis_host=redis \
-d config.redis_port=6379 \
-d config.limit_by=consumer # or ip, service, route
CORS
curl -X POST http://localhost:8001/services/users-api/plugins \
-d name=cors \
-d 'config.origins[]=https://app.company.com' \
-d 'config.methods[]=GET' \
-d 'config.methods[]=POST' \
-d 'config.headers[]=Authorization' \
-d 'config.headers[]=Content-Type' \
-d config.credentials=true
Request Transformer
curl -X POST http://localhost:8001/services/users-api/plugins \
-d name=request-transformer \
-d 'config.add.headers[]=X-Internal-Key:secret123' \
-d 'config.remove.headers[]=X-Forwarded-For' \
-d 'config.add.querystring[]=version:2'
Canary Deployments via Kong
# Create upstream
curl -X POST http://localhost:8001/upstreams -d name=api-upstream
# Add targets with weights
curl -X POST http://localhost:8001/upstreams/api-upstream/targets \
-d target=api-v1:3000 -d weight=90
curl -X POST http://localhost:8001/upstreams/api-upstream/targets \
-d target=api-v2:3000 -d weight=10
Observability
# Prometheus plugin
curl -X POST http://localhost:8001/plugins \
-d name=prometheus
# Grafana dashboard for Kong available as ID 7424 on grafana.com
Metrics in Prometheus:
kong_http_requests_total{service="users-api",route="users-route",status="200"}
kong_request_latency_ms{service="users-api",quantile="0.99"}
Management via Konga (Web UI)
docker run -d -p 1337:1337 \
-e NODE_ENV=production \
-e DB_ADAPTER=postgres \
-e DB_HOST=kong-db \
pantsel/konga
Timeline
Basic Kong setup with JWT, rate limiting, and routing — 2–3 business days. Full configuration with observability, canary deployments, and HA setup — 5–7 days.







