API Gateway Setup (APISIX) for Web Application
Apache APISIX is a high-performance API Gateway based on nginx/OpenResty with ETCD for configuration storage. Supports dynamic configuration updates without restart, 80+ plugins, and works in Kubernetes via Ingress Controller.
Architecture
Client → APISIX Gateway (nginx/OpenResty) → Upstream Services
↕
ETCD (config store)
↕
APISIX Dashboard
ETCD is required — it stores all configuration (routes, upstreams, plugins). Changes are applied in real-time via watch.
Docker Compose Installation
version: '3.8'
services:
etcd:
image: bitnami/etcd:3.5
environment:
ALLOW_NONE_AUTHENTICATION: "yes"
ETCD_ADVERTISE_CLIENT_URLS: http://etcd:2379
ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
apisix:
image: apache/apisix:3.9.1-debian
volumes:
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml
ports:
- "9080:9080" # HTTP
- "9443:9443" # HTTPS
- "9180:9180" # Admin API
- "9091:9091" # Prometheus metrics
depends_on: [etcd]
apisix-dashboard:
image: apache/apisix-dashboard:3.0.1-alpine
volumes:
- ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
ports:
- "9000:9000"
depends_on: [etcd]
# apisix_conf/config.yaml
apisix:
node_listen: 9080
enable_ipv6: false
enable_admin: true
admin_key:
- name: admin
key: supersecret-admin-key
role: admin
deployment:
admin:
admin_listen:
ip: 0.0.0.0
port: 9180
etcd:
host:
- "http://etcd:2379"
prefix: "/apisix"
timeout: 30
plugin_attr:
prometheus:
export_addr:
ip: 0.0.0.0
port: 9091
Creating a Route via Admin API
BASE_URL="http://localhost:9180/apisix/admin"
KEY="supersecret-admin-key"
# Create upstream
curl -X PUT $BASE_URL/upstreams/1 \
-H "X-API-KEY: $KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "roundrobin",
"nodes": {
"users-service:3000": 1,
"users-service-2:3000": 1
},
"checks": {
"active": {
"http_path": "/health",
"interval": 5,
"healthy": { "successes": 2 },
"unhealthy": { "http_failures": 3 }
}
}
}'
# Create route
curl -X PUT $BASE_URL/routes/1 \
-H "X-API-KEY: $KEY" \
-H "Content-Type: application/json" \
-d '{
"uri": "/api/v1/users/*",
"methods": ["GET", "POST", "PUT", "DELETE"],
"upstream_id": "1",
"plugins": {
"jwt-auth": {},
"rate-limiting": {
"count": 100,
"time_window": 60,
"key": "remote_addr",
"policy": "redis",
"redis_host": "redis",
"redis_port": 6379
},
"cors": {
"allow_origins": "https://app.company.com",
"allow_methods": "GET,POST,PUT,DELETE",
"allow_headers": "Authorization,Content-Type",
"allow_credential": true
}
}
}'
JWT Plugin
# Create consumer
curl -X PUT $BASE_URL/consumers/mobile-app \
-H "X-API-KEY: $KEY" \
-d '{
"username": "mobile-app",
"plugins": {
"jwt-auth": {
"key": "mobile-app-key",
"algorithm": "RS256",
"public_key": "-----BEGIN PUBLIC KEY-----\n..."
}
}
}'
Serverless Plugin (Custom Lua Logic)
curl -X PUT $BASE_URL/routes/2 \
-H "X-API-KEY: $KEY" \
-d '{
"uri": "/api/v1/transformed",
"upstream_id": "1",
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": [
"return function(conf, ctx)\n local headers = ngx.req.get_headers()\n ngx.req.set_header(\"X-Tenant-ID\", headers[\"X-User-Tenant\"])\n ngx.req.set_header(\"X-Internal-Key\", \"secret\")\nend"
]
}
}
}'
Canary Deployments via Traffic Split
curl -X PUT $BASE_URL/routes/3 \
-H "X-API-KEY: $KEY" \
-d '{
"uri": "/api/v2/feature",
"plugins": {
"traffic-split": {
"rules": [
{
"match": [
{ "vars": [["http_x-canary", "==", "true"]] }
],
"weighted_upstreams": [
{ "upstream_id": "2", "weight": 100 }
]
}
],
"weighted_upstreams": [
{ "upstream_id": "1", "weight": 90 },
{ "upstream_id": "2", "weight": 10 }
]
}
}
}'
OpenID Connect (OIDC)
{
"openid-connect": {
"client_id": "myapp",
"client_secret": "secret",
"discovery": "https://auth.company.com/.well-known/openid-configuration",
"redirect_uri": "https://api.company.com/callback",
"scope": "openid profile email",
"token_signing_alg_values_expected": ["RS256"],
"set_access_token_header": true,
"access_token_in_authorization_header": true
}
}
Monitoring
# prometheus.yml scrape config
scrape_configs:
- job_name: apisix
static_configs:
- targets: ['apisix:9091']
metrics_path: /apisix/prometheus/metrics
Grafana dashboard ID 11719 is the official APISIX dashboard.
Timeline
Installing APISIX with Dashboard, basic plugins (JWT, rate-limit, CORS), and health checks — 2–3 days. Full configuration with OIDC, traffic split, and Kubernetes Ingress — 5–7 days.







