Basic API Gateway
upstream users_service {
server 10.0.0.1:3001;
server 10.0.0.2:3001;
}
upstream orders_service {
server 10.0.0.3:3002;
server 10.0.0.4:3002;
}
upstream products_service {
server 10.0.0.5:3003;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# Route to services
location /api/users/ {
proxy_pass http://users_service/;
include snippets/proxy-headers.conf;
}
location /api/orders/ {
proxy_pass http://orders_service/;
include snippets/proxy-headers.conf;
}
location /api/products/ {
proxy_pass http://products_service/;
include snippets/proxy-headers.conf;
}
# Health check
location /health {
return 200 '{"status":"ok"}';
add_header Content-Type application/json;
}
}
API Gateway with Rate Limiting
# Rate limit zones
limit_req_zone $binary_remote_addr zone=api_general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api_auth:10m rate=3r/s;
limit_req_zone $http_authorization zone=api_user:10m rate=100r/s;
server {
listen 443 ssl http2;
server_name api.example.com;
# General API endpoints
location /api/ {
limit_req zone=api_general burst=20 nodelay;
proxy_pass http://backend;
}
# Auth endpoints (stricter)
location /api/auth/ {
limit_req zone=api_auth burst=5 nodelay;
proxy_pass http://auth_service;
}
# User-specific rate limit (by token)
location /api/v2/ {
limit_req zone=api_user burst=50 nodelay;
proxy_pass http://backend;
}
}
API Gateway with Auth
# Auth subrequest
server {
listen 443 ssl http2;
server_name api.example.com;
# Internal auth endpoint
location = /auth/validate {
internal;
proxy_pass http://auth_service/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
}
# Protected API endpoints
location /api/ {
auth_request /auth/validate;
auth_request_set $auth_user $upstream_http_x_user_id;
auth_request_set $auth_role $upstream_http_x_user_role;
proxy_pass http://backend;
proxy_set_header X-User-Id $auth_user;
proxy_set_header X-User-Role $auth_role;
}
# Public endpoints
location /api/public/ {
proxy_pass http://backend;
}
}
API Versioning
# Map-based versioning
map $http_accept $api_version {
default "v1";
~application/vnd.api.v1 "v1";
~application/vnd.api.v2 "v2";
~application/vnd.api.v3 "v3";
}
upstream api_v1 {
server 10.0.0.1:3000;
}
upstream api_v2 {
server 10.0.0.2:3000;
}
upstream api_v3 {
server 10.0.0.3:3000;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# URL-based versioning
location /v1/ {
proxy_pass http://api_v1/;
}
location /v2/ {
proxy_pass http://api_v2/;
}
location /v3/ {
proxy_pass http://api_v3/;
}
# Header-based versioning
location /api/ {
proxy_pass http://api_$api_version/;
}
}
CORS Configuration
# CORS snippet
# /etc/nginx/snippets/cors.conf
set $cors_origin "";
set $cors_methods "GET, POST, PUT, DELETE, OPTIONS";
set $cors_headers "Authorization, Content-Type, X-Requested-With";
if ($http_origin ~* (https://example\.com|https://app\.example\.com)) {
set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Methods $cors_methods always;
add_header Access-Control-Allow-Headers $cors_headers always;
add_header Access-Control-Max-Age 86400 always;
if ($request_method = OPTIONS) {
return 204;
}
Complete API Gateway
# Rate limits
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# Upstreams
upstream users { server 10.0.0.1:3001; }
upstream orders { server 10.0.0.2:3002; }
upstream auth { server 10.0.0.3:3003; }
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# Logging
access_log /var/log/nginx/api.access.log;
error_log /var/log/nginx/api.error.log;
# Rate limiting
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
# CORS
include snippets/cors.conf;
# Health
location /health {
return 200 '{"status":"ok"}';
add_header Content-Type application/json;
}
# Auth (public)
location /api/auth/ {
proxy_pass http://auth/;
include snippets/proxy-headers.conf;
}
# Protected routes
location /api/users/ {
auth_request /validate;
proxy_pass http://users/;
include snippets/proxy-headers.conf;
}
location /api/orders/ {
auth_request /validate;
proxy_pass http://orders/;
include snippets/proxy-headers.conf;
}
location = /validate {
internal;
proxy_pass http://auth/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Authorization $http_authorization;
}
}
advanced | Recipes | Updated 2025-01-15
- nginx
- api gateway
- microservices
- routing
- rate limiting