
Api Gateway Patterns
- 347 installs
- 61 repo stars
- Updated June 13, 2026
- manutej/luxor-claude-marketplace
api-gateway-patterns is a backend architecture skill that designs API gateways for routing, authentication, rate limiting, aggregation, and service-mesh boundaries for developers exposing multiple microservices behind on
About
api-gateway-patterns is a manutej/luxor-claude-marketplace skill that helps developers design API gateway layers for microservice estates. The skill covers request routing to upstream services, authentication and authorization at the edge, rate limiting and throttling, response aggregation across backends, and service-mesh boundary decisions when many services share one public entry. Developers reach for api-gateway-patterns when a growing service count needs consistent TLS termination, token validation, and quota enforcement instead of duplicating middleware in every repo. It fits greenfield gateway selection and brownfield refactors where BFF, edge proxy, or mesh ingress patterns must be chosen with clear failure and timeout semantics. The skill emphasizes architecture tradeoffs for production API platforms rather than single-endpoint CRUD tutorials.
- Routing and path-based proxying
- Authentication and authorization at edge
- Rate limiting and throttling
- Request aggregation and BFF patterns
- Observability and circuit breaking
Api Gateway Patterns by the numbers
- 347 all-time installs (skills.sh)
- +18 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #1,163 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/manutej/luxor-claude-marketplace --skill api-gateway-patternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 347 |
|---|---|
| repo stars | ★ 61 |
| Last updated | June 13, 2026 |
| Repository | manutej/luxor-claude-marketplace ↗ |
How do you design an API gateway for microservices?
Design API gateways for routing, auth, rate limiting, aggregation, and service mesh boundaries when exposing multiple microservices behind one edge.
Who is it for?
Backend developers exposing multiple microservices who need a single edge for routing, auth, rate limits, and response aggregation.
Skip if: Single-service CRUD APIs with no edge proxy needs or teams only tuning Redis caches without gateway concerns.
When should I use this skill?
Multiple backend services need one public entry point with routing, authentication, rate limiting, or response aggregation design.
What you get
Gateway architecture with routing rules, auth boundaries, rate-limit policies, aggregation patterns, and service-mesh edge decisions.
- gateway routing spec
- rate-limit and auth boundary design
Files
API Gateway Patterns
A comprehensive skill for implementing production-grade API gateways using Kong and industry best practices. This skill covers advanced routing, authentication, rate limiting, load balancing, traffic management, and observability patterns for microservices architectures.
When to Use This Skill
Use this skill when:
- Implementing an API gateway for microservices architectures
- Managing traffic routing, load balancing, and service discovery
- Implementing authentication and authorization at the gateway level
- Enforcing rate limiting, quotas, and traffic policies
- Adding observability, logging, and monitoring to API traffic
- Implementing request/response transformation and caching
- Managing API versioning and deprecation strategies
- Setting up circuit breakers and resilience patterns
- Configuring multi-environment API deployments
- Implementing API security policies (CORS, CSRF, WAF)
- Building developer portals and API documentation
- Managing API lifecycle from development to production
Core Concepts
API Gateway Architecture
An API gateway acts as a single entry point for client applications, routing requests to appropriate backend services while providing cross-cutting concerns:
- Reverse Proxy: Routes client requests to backend services
- API Composition: Aggregates multiple service calls into single responses
- Protocol Translation: Converts between protocols (HTTP, gRPC, WebSocket)
- Cross-Cutting Concerns: Authentication, logging, rate limiting, caching
- Traffic Management: Load balancing, circuit breaking, retries
- Security: SSL termination, API key validation, OAuth2 flows
Key Gateway Components
1. Services: Upstream APIs that the gateway proxies to 2. Routes: Request matching rules that determine service routing 3. Upstreams: Load balancer configurations for service instances 4. Plugins: Extensible middleware for features (auth, logging, etc.) 5. Consumers: API clients with authentication credentials 6. Certificates: SSL/TLS certificates for secure communication 7. SNIs: Server Name Indication for multi-domain SSL
Kong Gateway Fundamentals
Kong is a cloud-native, platform-agnostic, scalable API gateway:
Architecture:
- Control Plane: Admin API for configuration management
- Data Plane: Proxy layer handling runtime traffic
- Database: PostgreSQL or Cassandra for config storage (or DB-less mode)
- Plugin System: Lua-based extensibility for custom logic
Core Entities:
Service (upstream API)
└── Routes (request matching)
└── Plugins (features/policies)
Upstream (load balancer)
└── Targets (service instances)
Consumer (API client)
└── Credentials (auth keys/tokens)
└── Plugins (consumer-specific policies)Routing Patterns
Pattern 1: Path-Based Routing
Route requests based on URL paths to different backend services.
Use Case: Microservices with distinct URL prefixes (e.g., /users, /orders, /products)
Configuration:
# Users Service
service:
name: users-service
url: http://users-api:8001
routes:
- name: users-route
paths:
- /users
- /api/users
strip_path: true
methods:
- GET
- POST
- PUT
- DELETE
# Orders Service
service:
name: orders-service
url: http://orders-api:8002
routes:
- name: orders-route
paths:
- /orders
- /api/orders
strip_path: trueKey Options:
strip_path: true- Removes matched path before proxying (e.g., /users/123 → /123)strip_path: false- Preserves full path (e.g., /users/123 → /users/123)preserve_host: true- Forwards original Host header to upstream
Pattern 2: Header-Based Routing
Route based on HTTP headers for A/B testing, canary deployments, or API versioning.
Use Case: Gradual rollout of new API versions or feature flags
Configuration:
# V1 Service (stable)
service:
name: api-v1
url: http://api-v1:8001
routes:
- name: api-v1-route
paths:
- /api
headers:
X-API-Version:
- "1"
- "1.0"
# V2 Service (beta)
service:
name: api-v2
url: http://api-v2:8002
routes:
- name: api-v2-route
paths:
- /api
headers:
X-API-Version:
- "2"
- "2.0"
# Default route (no version header)
routes:
- name: api-default
paths:
- /api
# Routes to V1 by defaultAdvanced Header Routing:
# Mobile vs Web routing
routes:
- name: mobile-api
headers:
User-Agent:
- ".*Mobile.*"
- ".*Android.*"
- ".*iOS.*"
service: mobile-optimized-api
- name: web-api
headers:
User-Agent:
- ".*Chrome.*"
- ".*Firefox.*"
- ".*Safari.*"
service: web-apiPattern 3: Method-Based Routing
Route different HTTP methods to specialized services.
Use Case: CQRS pattern - separate read and write services
Configuration:
# Read Service (queries)
service:
name: query-service
url: http://read-api:8001
routes:
- name: read-operations
paths:
- /api/resources
methods:
- GET
- HEAD
- OPTIONS
# Write Service (commands)
service:
name: command-service
url: http://write-api:8002
routes:
- name: write-operations
paths:
- /api/resources
methods:
- POST
- PUT
- PATCH
- DELETEPattern 4: Host-Based Routing
Route based on the requested hostname for multi-tenant applications.
Use Case: Different subdomains for different customers or environments
Configuration:
# Tenant A
service:
name: tenant-a-api
url: http://tenant-a:8001
routes:
- name: tenant-a-route
hosts:
- tenant-a.api.example.com
- a.api.example.com
# Tenant B
service:
name: tenant-b-api
url: http://tenant-b:8002
routes:
- name: tenant-b-route
hosts:
- tenant-b.api.example.com
- b.api.example.com
# Wildcard for dynamic tenants
routes:
- name: dynamic-tenant
hosts:
- "*.api.example.com"
service: multi-tenant-apiPattern 5: Weighted Routing (Canary Deployments)
Gradually shift traffic between service versions.
Implementation:
# Create two upstreams with weight distribution
upstream:
name: api-upstream
algorithm: round-robin
targets:
- target: api-v1:8001
weight: 90 # 90% traffic to stable version
- target: api-v2:8002
weight: 10 # 10% traffic to canary version
service:
name: api-service
host: api-upstream # Points to upstream
routes:
- name: api-route
paths:
- /apiGradual Rollout Strategy: 1. Start: 100% v1, 0% v2 2. Phase 1: 90% v1, 10% v2 (monitor metrics) 3. Phase 2: 75% v1, 25% v2 4. Phase 3: 50% v1, 50% v2 5. Phase 4: 25% v1, 75% v2 6. Complete: 0% v1, 100% v2
Rate Limiting Patterns
Pattern 1: Global Rate Limiting
Protect your entire API from abuse with global limits.
Use Case: Prevent DDoS attacks and ensure fair usage
Configuration:
plugins:
- name: rate-limiting
config:
minute: 1000
hour: 10000
day: 100000
policy: local # or 'cluster', 'redis'
fault_tolerant: true
hide_client_headers: false
limit_by: ip # or 'consumer', 'credential', 'service'Policy Options:
local: In-memory, single node (not cluster-safe)cluster: Shared across Kong nodes via databaseredis: High-performance distributed limiting via Redis
Pattern 2: Consumer-Specific Rate Limiting
Different limits for different API consumers (tiers).
Use Case: Freemium model with tiered pricing
Configuration:
# Free tier consumer
consumer:
username: free-user-123
plugins:
- name: rate-limiting
consumer: free-user-123
config:
minute: 10
hour: 100
day: 1000
# Premium tier consumer
consumer:
username: premium-user-456
plugins:
- name: rate-limiting
consumer: premium-user-456
config:
minute: 1000
hour: 10000
day: 100000
# Enterprise tier (unlimited)
consumer:
username: enterprise-user-789
# No rate limiting plugin for enterprisePattern 3: Endpoint-Specific Rate Limiting
Different limits for different API endpoints.
Use Case: Protect expensive operations while allowing higher rates for cheap ones
Configuration:
# Expensive search endpoint - strict limits
routes:
- name: search-route
paths:
- /api/search
plugins:
- name: rate-limiting
route: search-route
config:
minute: 10
hour: 100
# Regular CRUD endpoints - moderate limits
routes:
- name: users-route
paths:
- /api/users
plugins:
- name: rate-limiting
route: users-route
config:
minute: 100
hour: 1000
# Health check - no limits
routes:
- name: health-route
paths:
- /health
# No rate limiting pluginPattern 4: Sliding Window Rate Limiting
More accurate rate limiting using sliding windows.
Use Case: Prevent burst attacks that exploit fixed window boundaries
Configuration:
plugins:
- name: rate-limiting-advanced # Kong Enterprise
config:
limit:
- 100 # Limit value
window_size:
- 60 # Window in seconds
window_type: sliding
retry_after_jitter_max: 1
sync_rate: 0.5
namespace: my-api
strategy: redis
redis:
host: redis
port: 6379
database: 0Sliding vs Fixed Windows:
- Fixed: 100 requests per minute resets at :00 seconds
- Sliding: 100 requests in any 60-second window
- Sliding prevents burst exploitation at window boundaries
Pattern 5: Quota Management
Long-term usage quotas (monthly, yearly).
Use Case: Enforce subscription limits based on plan
Configuration:
plugins:
- name: request-termination
enabled: false # Will be enabled when quota exceeded
plugins:
- name: acme # Custom quota tracking plugin
config:
quota:
month: 1000000
reset_on: first_day
consumer_groups:
- name: starter
quota: 10000
- name: professional
quota: 100000
- name: enterprise
quota: 1000000Authentication Patterns
Pattern 1: API Key Authentication
Simple API key validation for basic security.
Use Case: Internal APIs, development environments, simple integrations
Configuration:
# Enable key-auth plugin
plugins:
- name: key-auth
config:
key_names:
- apikey
- api-key
- X-API-Key
hide_credentials: true
anonymous: null # Require authentication
run_on_preflight: false
# Create consumer with API key
consumers:
- username: mobile-app
custom_id: app-001
# Add key credential
keyauth_credentials:
- consumer: mobile-app
key: sk_live_abc123def456ghi789Usage:
curl -H "apikey: sk_live_abc123def456ghi789" \
https://api.example.com/usersBest Practices:
- Use cryptographically random keys (min 32 chars)
- Rotate keys periodically
- Different keys for different environments
- Never commit keys to version control
- Use HTTPS to protect keys in transit
Pattern 2: JWT Authentication
Token-based authentication with payload verification.
Use Case: Modern SPAs, mobile apps, microservices
Configuration:
plugins:
- name: jwt
config:
uri_param_names:
- jwt
cookie_names:
- jwt_token
header_names:
- Authorization
claims_to_verify:
- exp
- nbf
key_claim_name: iss
secret_is_base64: false
anonymous: null
run_on_preflight: false
maximum_expiration: 3600 # 1 hour max
# Create consumer with JWT credential
consumers:
- username: web-app
jwt_secrets:
- consumer: web-app
key: myapp-issuer
algorithm: HS256
secret: my-secret-key-change-in-productionRS256 (Asymmetric) Configuration:
jwt_secrets:
- consumer: mobile-app
key: mobile-issuer
algorithm: RS256
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----Token Format:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJteWFwcC1pc3N1ZXIiLCJzdWIiOiJ1c2VyMTIzIiwiZXhwIjoxNjQwOTk1MjAwfQ.signaturePattern 3: OAuth 2.0 Authorization
Full OAuth 2.0 flows for third-party integrations.
Use Case: Public APIs, third-party developer access
Supported Flows:
- Authorization Code Flow
- Client Credentials Flow
- Implicit Flow (deprecated)
- Resource Owner Password Flow
Configuration:
plugins:
- name: oauth2
config:
scopes:
- read
- write
- admin
mandatory_scope: true
token_expiration: 3600
enable_authorization_code: true
enable_client_credentials: true
enable_implicit_grant: false
enable_password_grant: false
hide_credentials: true
accept_http_if_already_terminated: false
refresh_token_ttl: 1209600 # 14 days
# Create OAuth application
oauth2_credentials:
- consumer: third-party-app
name: "Partner Integration"
client_id: client_abc123
client_secret: secret_xyz789
redirect_uris:
- https://partner.com/callbackAuthorization Code Flow:
# 1. Get authorization code
GET /oauth2/authorize?
response_type=code&
client_id=client_abc123&
redirect_uri=https://partner.com/callback&
scope=read write
# 2. Exchange code for token
POST /oauth2/token
grant_type=authorization_code&
client_id=client_abc123&
client_secret=secret_xyz789&
code=AUTH_CODE&
redirect_uri=https://partner.com/callbackPattern 4: OpenID Connect (OIDC)
Enterprise SSO integration with identity providers.
Use Case: Enterprise authentication with Google, Okta, Auth0, Azure AD
Configuration:
plugins:
- name: openid-connect
config:
issuer: https://accounts.google.com
client_id: your-client-id.apps.googleusercontent.com
client_secret: your-client-secret
redirect_uri:
- https://api.example.com/callback
scopes:
- openid
- email
- profile
auth_methods:
- authorization_code
login_redirect_uri: https://app.example.com/login
logout_redirect_uri: https://app.example.com/logout
ssl_verify: true
session_secret: change-this-secret-in-production
discovery: https://accounts.google.com/.well-known/openid-configurationMulti-Provider Configuration:
# Google OIDC
plugins:
- name: openid-connect
route: google-login
config:
issuer: https://accounts.google.com
client_id: google-client-id
client_secret: google-secret
# Azure AD OIDC
plugins:
- name: openid-connect
route: azure-login
config:
issuer: https://login.microsoftonline.com/tenant-id/v2.0
client_id: azure-client-id
client_secret: azure-secret
# Okta OIDC
plugins:
- name: openid-connect
route: okta-login
config:
issuer: https://dev-123456.okta.com
client_id: okta-client-id
client_secret: okta-secretPattern 5: mTLS (Mutual TLS) Authentication
Certificate-based authentication for service-to-service security.
Use Case: Microservices mutual authentication, B2B integrations
Configuration:
# Enable mTLS plugin
plugins:
- name: mtls-auth
config:
ca_certificates:
- ca-cert-id-1
- ca-cert-id-2
skip_consumer_lookup: false
anonymous: null
revocation_check_mode: SKIP # or IGNORE_CA_ERROR, STRICT
# Upload CA certificate
ca_certificates:
- cert: |
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL...
-----END CERTIFICATE-----
# Create consumer mapped to client certificate
consumers:
- username: service-a
custom_id: service-a-001
# Map certificate to consumer
mtls_auth_credentials:
- consumer: service-a
subject_name: CN=service-a,O=MyOrgLoad Balancing Patterns
Pattern 1: Round-Robin Load Balancing
Distribute requests evenly across service instances.
Use Case: Stateless services with uniform capacity
Configuration:
upstreams:
- name: api-upstream
algorithm: round-robin
slots: 10000
healthchecks:
active:
type: http
http_path: /health
healthy:
interval: 5
successes: 2
unhealthy:
interval: 5
http_failures: 3
timeouts: 3
passive:
healthy:
successes: 5
unhealthy:
http_failures: 5
timeouts: 2
targets:
- upstream: api-upstream
target: api-1.internal:8001
weight: 100
- upstream: api-upstream
target: api-2.internal:8001
weight: 100
- upstream: api-upstream
target: api-3.internal:8001
weight: 100Pattern 2: Weighted Load Balancing
Distribute traffic proportionally based on server capacity.
Use Case: Heterogeneous servers with different capacities
Configuration:
upstreams:
- name: api-upstream
algorithm: round-robin
targets:
# Powerful server - 50% traffic
- target: api-1.internal:8001
weight: 500
# Medium server - 30% traffic
- target: api-2.internal:8001
weight: 300
# Small server - 20% traffic
- target: api-3.internal:8001
weight: 200Weight Distribution:
- Total weight: 500 + 300 + 200 = 1000
- api-1: 500/1000 = 50% of requests
- api-2: 300/1000 = 30% of requests
- api-3: 200/1000 = 20% of requests
Pattern 3: Consistent Hashing
Route requests from same client to same backend (session affinity).
Use Case: Stateful services requiring session persistence
Configuration:
upstreams:
- name: api-upstream
algorithm: consistent-hashing
hash_on: header
hash_on_header: X-User-ID
hash_fallback: ip
hash_fallback_header: X-Forwarded-For
targets:
- target: api-1.internal:8001
- target: api-2.internal:8001
- target: api-3.internal:8001Hashing Options:
hash_on: none- Random distributionhash_on: consumer- Hash by authenticated consumerhash_on: ip- Hash by client IPhash_on: header- Hash by specified header valuehash_on: cookie- Hash by cookie valuehash_on: path- Hash by request path
Use Cases by Hash Type:
- User sessions:
hash_on: header(X-User-ID) - Geographic routing:
hash_on: ip - Tenant isolation:
hash_on: header(X-Tenant-ID) - Shopping carts:
hash_on: cookie(session_id)
Pattern 4: Least Connections
Route to server with fewest active connections.
Use Case: Long-lived connections (WebSockets, streaming)
Configuration:
upstreams:
- name: websocket-upstream
algorithm: least-connections
targets:
- target: ws-1.internal:8001
- target: ws-2.internal:8001
- target: ws-3.internal:8001When to Use:
- WebSocket servers
- Long-polling endpoints
- Streaming APIs (SSE, gRPC streaming)
- Services with variable request duration
Pattern 5: Active Health Checks
Automatically remove unhealthy targets from rotation.
Use Case: High availability with automatic failover
Configuration:
upstreams:
- name: api-upstream
healthchecks:
active:
type: http
http_path: /health
https_verify_certificate: true
concurrency: 10
timeout: 1
headers:
X-Health-Check:
- gateway
healthy:
interval: 5 # Check every 5 seconds
http_statuses:
- 200
- 302
successes: 2 # 2 successes → healthy
unhealthy:
interval: 5
http_statuses:
- 429
- 500
- 503
http_failures: 3 # 3 failures → unhealthy
tcp_failures: 3
timeouts: 3
passive:
type: http
healthy:
http_statuses:
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 226
- 300
- 301
- 302
successes: 5
unhealthy:
http_statuses:
- 429
- 500
- 503
http_failures: 5
tcp_failures: 2
timeouts: 2Traffic Control Patterns
Pattern 1: Circuit Breaker
Prevent cascading failures by failing fast when downstream is unhealthy.
Use Case: Protect your system when dependencies fail
Configuration:
plugins:
- name: proxy-cache-advanced # Kong Enterprise
config:
# Serve stale cache during outages
cache_control: false
plugins:
- name: request-termination
enabled: false # Enabled programmatically on circuit open
# Custom circuit breaker (via passive health checks)
upstreams:
- name: api-upstream
healthchecks:
passive:
unhealthy:
http_failures: 5 # Open circuit after 5 failures
timeouts: 3
healthy:
successes: 3 # Close circuit after 3 successesCircuit States: 1. Closed: Normal operation, requests flow through 2. Open: Failures detected, requests fail immediately 3. Half-Open: Test if service recovered, allow limited requests
Pattern 2: Request Timeout
Prevent slow requests from tying up resources.
Use Case: Prevent resource exhaustion from slow backends
Configuration:
services:
- name: api-service
url: http://api.internal:8001
read_timeout: 5000 # 5 seconds
write_timeout: 5000 # 5 seconds
connect_timeout: 2000 # 2 seconds
plugins:
- name: request-timeout # Additional timeout enforcement
config:
http_timeout: 5000
stream_timeout: 30000Timeout Strategy:
connect_timeout: 2s → Connection establishment
write_timeout: 5s → Writing request to upstream
read_timeout: 5s → Reading response from upstream
http_timeout: 5s → Overall HTTP transactionPattern 3: Retry Logic
Automatically retry failed requests with exponential backoff.
Use Case: Handle transient failures in distributed systems
Configuration:
services:
- name: api-service
retries: 5 # Maximum retry attempts
plugins:
- name: proxy-retry # Custom retry plugin
config:
retries: 3
retry_on:
- 500
- 502
- 503
- 504
backoff:
type: exponential
base: 2
max: 30
jitter: 0.5Retry Schedule:
Attempt 1: Immediate
Attempt 2: 2s + jitter
Attempt 3: 4s + jitter
Attempt 4: 8s + jitter
Attempt 5: 16s + jitterIdempotency Considerations:
- Retry GET, HEAD, PUT, DELETE (idempotent)
- DO NOT retry POST unless idempotency keys used
- Check for Idempotency-Key header
Pattern 4: Request Size Limiting
Prevent large payload attacks and memory exhaustion.
Use Case: Protect against oversized request bodies
Configuration:
plugins:
- name: request-size-limiting
config:
allowed_payload_size: 10 # Megabytes
size_unit: megabytes
require_content_length: true
# Different limits per route
plugins:
- name: request-size-limiting
route: file-upload
config:
allowed_payload_size: 100 # Allow larger files
- name: request-size-limiting
route: api-endpoints
config:
allowed_payload_size: 1 # Strict limit for APIsPattern 5: Traffic Shaping (Throttling)
Control request rate beyond simple rate limiting.
Use Case: Smooth traffic spikes, prevent backend overload
Configuration:
plugins:
- name: request-transformer-advanced
config:
# Add delay headers for client-side throttling
add:
headers:
- "Retry-After:60"
plugins:
- name: proxy-cache-advanced
config:
# Cache responses to reduce backend load
cache_ttl: 300
strategy: memory
# Upstream connection limits
upstreams:
- name: api-upstream
slots: 1000 # Limit concurrent connectionsRequest/Response Transformation
Pattern 1: Request Header Manipulation
Add, modify, or remove request headers before proxying.
Use Case: Add authentication, tracing, or context headers
Configuration:
plugins:
- name: request-transformer
config:
add:
headers:
- "X-Gateway:kong"
- "X-Request-ID:$(uuid)"
- "X-Forwarded-Proto:https"
append:
headers:
- "X-Trace-Id:$(uuid)"
replace:
headers:
- "User-Agent:Kong-Gateway/3.0"
remove:
headers:
- "X-Internal-Secret"Advanced Transformations:
plugins:
- name: request-transformer-advanced
config:
add:
headers:
- "X-Consumer-Username:$(consumer_username)"
- "X-Consumer-ID:$(consumer_id)"
- "X-Authenticated-Scope:$(authenticated_credential.scope)"
- "X-Client-IP:$(remote_addr)"
rename:
headers:
- "Authorization:X-Original-Auth"Pattern 2: Response Header Manipulation
Modify response headers before returning to client.
Use Case: Add security headers, CORS, caching directives
Configuration:
plugins:
- name: response-transformer
config:
add:
headers:
- "X-Gateway-Response-Time:$(latencies.request)"
- "X-Server-ID:$(upstream_addr)"
remove:
headers:
- "X-Powered-By"
- "Server"
# Security headers
plugins:
- name: response-transformer
config:
add:
headers:
- "Strict-Transport-Security:max-age=31536000; includeSubDomains"
- "X-Content-Type-Options:nosniff"
- "X-Frame-Options:DENY"
- "X-XSS-Protection:1; mode=block"
- "Content-Security-Policy:default-src 'self'"Pattern 3: Request Body Transformation
Modify request payloads before forwarding.
Use Case: Add fields, transform formats, sanitize input
Configuration:
plugins:
- name: request-transformer-advanced
config:
add:
body:
- "gateway_timestamp:$(timestamp)"
- "request_id:$(uuid)"
remove:
body:
- "internal_field"
replace:
body:
- "api_version:v2"Pattern 4: GraphQL to REST Translation
Expose REST APIs as GraphQL endpoints.
Use Case: Modernize legacy REST APIs with GraphQL
Configuration:
plugins:
- name: graphql-proxy-cache-advanced
config:
strategy: memory
# Define GraphQL schema mapping
graphql_schemas:
- name: users-graphql
schema: |
type Query {
user(id: ID!): User
users: [User]
}
type User {
id: ID!
name: String!
email: String!
}
resolvers:
Query:
user: http://users-api/users/{id}
users: http://users-api/usersPattern 5: Protocol Translation
Convert between HTTP, gRPC, and WebSocket protocols.
Use Case: Expose gRPC services via HTTP/JSON
Configuration:
# gRPC to HTTP/JSON
plugins:
- name: grpc-gateway
config:
proto: /path/to/service.proto
services:
- name: grpc-service
url: grpc://grpc.internal:9000
protocol: grpc
routes:
- name: grpc-http-route
paths:
- /v1/users
protocols:
- http
- httpsCaching Patterns
Pattern 1: Response Caching
Cache upstream responses to reduce backend load.
Use Case: Cache expensive queries, reduce database load
Configuration:
plugins:
- name: proxy-cache
config:
strategy: memory # or 'redis'
content_type:
- "application/json"
- "text/html"
cache_ttl: 300 # 5 minutes
cache_control: false # Ignore client cache headers
storage_ttl: 600 # Backend storage TTL
memory:
dictionary_name: kong_cache
vary_headers:
- "Accept-Language"
- "X-User-Tier"Redis-Based Caching:
plugins:
- name: proxy-cache-advanced
config:
strategy: redis
cache_ttl: 3600
redis:
host: redis.internal
port: 6379
database: 0
password: redis-password
timeout: 2000
sentinel_master: mymaster
sentinel_addresses:
- redis-sentinel-1:26379
- redis-sentinel-2:26379Pattern 2: Conditional Caching
Cache based on status codes, headers, or request criteria.
Use Case: Cache only successful responses, skip errors
Configuration:
plugins:
- name: proxy-cache-advanced
config:
response_code:
- 200
- 301
- 302
request_method:
- GET
- HEAD
vary_headers:
- "Accept"
- "Accept-Encoding"
vary_query_params:
- "page"
- "limit"
ignore_uri_case: truePattern 3: Cache Invalidation
Purge cache on-demand or based on events.
Use Case: Update cache when data changes
Configuration:
# Admin API cache purge
POST /cache/purge
# Purge specific endpoint
POST /cache/purge/users
# TTL-based expiration
plugins:
- name: proxy-cache
config:
cache_ttl: 60 # Short TTL for frequently updated data
# Event-based invalidation (custom plugin)
plugins:
- name: custom-cache-invalidator
config:
invalidate_on:
- POST
- PUT
- PATCH
- DELETE
propagate: true # Clear related cachesPattern 4: Multi-Tier Caching
Layer caching at gateway and backend.
Use Case: Maximize cache hit rate across layers
Architecture:
Client
↓
Kong Gateway Cache (L1)
↓
Backend API Cache (L2)
↓
DatabaseConfiguration:
# Gateway cache (L1)
plugins:
- name: proxy-cache
config:
strategy: memory
cache_ttl: 60 # 1 minute
# Backend passes Cache-Control headers
# Gateway respects them if cache_control: true
plugins:
- name: proxy-cache
config:
cache_control: true # Respect upstream Cache-Control
vary_headers:
- "Cache-Control"Pattern 5: Surrogate-Key Based Invalidation
Tag caches for granular invalidation.
Use Case: Invalidate related resources efficiently
Configuration:
# Tag responses with surrogate keys
plugins:
- name: response-transformer
config:
add:
headers:
- "Surrogate-Key:user-$(user_id) tenant-$(tenant_id)"
# Invalidate by surrogate key
# Custom plugin or Varnish integration
POST /cache/purge
Headers:
Surrogate-Key: user-123Security Patterns
Pattern 1: CORS (Cross-Origin Resource Sharing)
Enable controlled cross-origin requests.
Use Case: Web apps calling APIs from different domains
Configuration:
plugins:
- name: cors
config:
origins:
- "https://app.example.com"
- "https://admin.example.com"
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
headers:
- Accept
- Authorization
- Content-Type
- X-Request-ID
exposed_headers:
- X-Total-Count
- X-Page-Number
credentials: true
max_age: 3600
preflight_continue: falseWildcard CORS (Development Only):
plugins:
- name: cors
config:
origins:
- "*"
methods:
- "*"
headers:
- "*"
credentials: false # Must be false with wildcard originsPattern 2: IP Restriction
Allow or deny based on IP addresses.
Use Case: Restrict admin APIs to office IPs
Configuration:
# Whitelist approach
plugins:
- name: ip-restriction
config:
allow:
- 10.0.0.0/8
- 192.168.1.100
- 203.0.113.0/24
# Blacklist approach
plugins:
- name: ip-restriction
config:
deny:
- 1.2.3.4
- 5.6.7.0/24Combined with Authentication:
# Admin route: IP + Auth
plugins:
- name: ip-restriction
route: admin-api
config:
allow:
- 10.0.0.0/8
- name: key-auth
route: admin-apiPattern 3: Bot Detection
Detect and block malicious bots.
Use Case: Prevent scraping, brute force, spam
Configuration:
plugins:
- name: bot-detection
config:
allow:
- "googlebot"
- "bingbot"
- "slackbot"
deny:
- "curl"
- "wget"
- "scrapy"
blacklist_cache_size: 10000
whitelist_cache_size: 10000Pattern 4: Request Validation
Validate requests against schemas.
Use Case: Ensure API contract compliance, prevent injection
Configuration:
plugins:
- name: request-validator
config:
body_schema: |
{
"type": "object",
"properties": {
"username": {
"type": "string",
"minLength": 3,
"maxLength": 50
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 120
}
},
"required": ["username", "email"]
}
parameter_schema:
- name: page
in: query
required: false
schema:
type: integer
minimum: 1Pattern 5: WAF (Web Application Firewall)
Protect against OWASP Top 10 vulnerabilities.
Use Case: Block SQL injection, XSS, path traversal
Configuration:
plugins:
- name: waf # Kong Enterprise or ModSecurity plugin
config:
rule_sets:
- owasp_crs
anomaly_threshold: 5
paranoia_level: 1
blocked_status_code: 403Observability Patterns
Pattern 1: Request Logging
Log all API requests for audit and debugging.
Use Case: Compliance, debugging, analytics
Configuration:
plugins:
- name: file-log
config:
path: /var/log/kong/requests.log
reopen: true
# JSON structured logging
plugins:
- name: http-log
config:
http_endpoint: http://logstash:5000
method: POST
content_type: application/json
timeout: 5000
keepalive: 60000
custom_fields_by_lua:
request_id: "return kong.request.get_header('X-Request-ID')"Log to Multiple Destinations:
# Elasticsearch
plugins:
- name: http-log
config:
http_endpoint: http://elasticsearch:9200/_bulk
# Splunk
plugins:
- name: http-log
config:
http_endpoint: https://splunk:8088/services/collector
headers:
Authorization: "Splunk token"
# Datadog
plugins:
- name: datadog
config:
host: datadog-agent
port: 8125Pattern 2: Distributed Tracing
Track requests across microservices.
Use Case: Diagnose latency, understand request flow
Configuration:
# Zipkin
plugins:
- name: zipkin
config:
http_endpoint: http://zipkin:9411/api/v2/spans
sample_ratio: 0.1 # Trace 10% of requests
include_credential: true
traceid_byte_count: 16
header_type: preserve # or 'jaeger', 'b3', 'w3c'
# Jaeger
plugins:
- name: opentelemetry
config:
endpoint: http://jaeger:14268/api/traces
resource_attributes:
service.name: api-gateway
service.version: 1.0.0
batch_span_processor:
max_queue_size: 2048
batch_timeout: 5000W3C Trace Context:
plugins:
- name: opentelemetry
config:
propagation:
default: w3c
headers:
- traceparent
- tracestatePattern 3: Metrics Collection
Expose Prometheus metrics for monitoring.
Use Case: Monitor gateway performance, errors, latency
Configuration:
plugins:
- name: prometheus
config:
per_consumer: true
status_code_metrics: true
latency_metrics: true
bandwidth_metrics: true
upstream_health_metrics: true
# Expose /metrics endpoint
routes:
- name: metrics
paths:
- /metrics
service: prometheus-serviceAvailable Metrics:
# Requests
kong_http_requests_total{service,route,code}
# Latency
kong_latency_ms{type,service,route}
kong_request_latency_ms{service,route}
kong_upstream_latency_ms{service,route}
# Bandwidth
kong_bandwidth_bytes{type,service,route}
# Connections
kong_datastore_reachable
kong_nginx_connections_total{state}Pattern 4: Health Checks
Expose health check endpoints.
Use Case: Kubernetes liveness/readiness probes
Configuration:
# Gateway health
routes:
- name: health
paths:
- /health
plugins:
- name: request-termination
config:
status_code: 200
message: "OK"
# Detailed status
routes:
- name: status
paths:
- /status
service: kong-status-service
# Upstream health aggregation
plugins:
- name: upstream-health-check
config:
healthy_threshold: 2
unhealthy_threshold: 3Pattern 5: Error Tracking
Track and report errors to monitoring systems.
Use Case: Proactive error detection and alerting
Configuration:
# Sentry integration
plugins:
- name: sentry
config:
dsn: https://key@sentry.io/project
environment: production
release: v1.2.3
# Custom error logging
plugins:
- name: http-log
config:
http_endpoint: http://error-tracker:5000
custom_fields_by_lua:
error_type: |
if kong.response.get_status() >= 500 then
return "server_error"
elseif kong.response.get_status() >= 400 then
return "client_error"
endMulti-Environment Patterns
Pattern 1: Environment Separation
Separate configurations for dev, staging, production.
Use Case: Consistent deployment across environments
Structure:
config/
├── base.yaml # Shared configuration
├── dev.yaml # Development overrides
├── staging.yaml # Staging overrides
└── production.yaml # Production overridesConfiguration:
# base.yaml
_format_version: "3.0"
services:
- name: users-api
url: http://users-service:8001
routes:
- name: users-route
service: users-api
paths:
- /users
# production.yaml
_format_version: "3.0"
services:
- name: users-api
url: https://users-api-prod.internal:8001
retries: 5
read_timeout: 5000
plugins:
- name: rate-limiting
service: users-api
config:
minute: 1000Pattern 2: Blue-Green Deployments
Zero-downtime deployments with instant rollback.
Use Case: Safe production deployments
Configuration:
# Blue environment (current production)
upstreams:
- name: api-blue
targets:
- target: api-blue-1:8001
- target: api-blue-2:8001
# Green environment (new version)
upstreams:
- name: api-green
targets:
- target: api-green-1:8001
- target: api-green-2:8001
# Route points to active environment
services:
- name: api-service
host: api-blue # Switch to api-green for deployment
# Rollback: Switch service.host back to api-bluePattern 3: Canary Releases
Gradual rollout with monitoring.
Use Case: Risk mitigation for new releases
Configuration:
# Canary routing with header
routes:
- name: api-canary
paths:
- /api
headers:
X-Canary:
- "true"
service: api-v2
routes:
- name: api-stable
paths:
- /api
service: api-v1
# Weighted canary (10% traffic)
upstreams:
- name: api-upstream
targets:
- target: api-v1:8001
weight: 90
- target: api-v2:8001
weight: 10Canary Progression:
Phase 1: 5% canary, monitor errors
Phase 2: 25% canary, check metrics
Phase 3: 50% canary, verify performance
Phase 4: 100% canary, deprecate old versionPattern 4: Feature Flags
Enable/disable features dynamically.
Use Case: A/B testing, gradual feature rollout
Configuration:
# Feature flag via header
routes:
- name: new-feature
paths:
- /api/new-feature
headers:
X-Feature-Flag:
- "new-dashboard"
service: new-feature-service
# Default route (feature disabled)
routes:
- name: old-feature
paths:
- /api/new-feature
service: old-feature-service
# Consumer-based feature flags
plugins:
- name: request-transformer
consumer: beta-users
config:
add:
headers:
- "X-Feature-Flags:new-dashboard,advanced-search"Pattern 5: Multi-Region Deployment
Route to nearest region for low latency.
Use Case: Global API with regional failover
Configuration:
# US region
upstreams:
- name: api-us
targets:
- target: api-us-east:8001
- target: api-us-west:8001
# EU region
upstreams:
- name: api-eu
targets:
- target: api-eu-west:8001
- target: api-eu-central:8001
# Geographic routing (via DNS or header)
routes:
- name: us-traffic
hosts:
- us.api.example.com
service: api-us-service
routes:
- name: eu-traffic
hosts:
- eu.api.example.com
service: api-eu-serviceBest Practices
Architecture Design
1. Single Responsibility: Gateway handles cross-cutting concerns only 2. Stateless Design: Keep gateway stateless for horizontal scaling 3. Declarative Configuration: Use YAML/JSON for version-controlled config 4. Database-Less Mode: Use DB-less for simpler deployments 5. Plugin Minimalism: Only enable necessary plugins
Security Best Practices
1. Defense in Depth: Layer multiple security mechanisms 2. Least Privilege: Minimal permissions for consumers 3. Secrets Management: Never hardcode credentials 4. TLS Everywhere: Encrypt all traffic (client and upstream) 5. Rate Limiting: Always protect public endpoints 6. Input Validation: Validate all request data 7. Regular Updates: Keep Kong and plugins updated
Performance Optimization
1. Enable Caching: Cache responses aggressively 2. Connection Pooling: Reuse upstream connections 3. Load Balancing: Distribute load evenly 4. Health Checks: Remove unhealthy targets quickly 5. Timeouts: Set appropriate timeouts to prevent hangs 6. Monitoring: Track latency, errors, throughput 7. Resource Limits: Set memory and connection limits
Operational Excellence
1. Logging: Structured logging for all requests 2. Monitoring: Comprehensive metrics collection 3. Alerting: Alert on anomalies and errors 4. Documentation: Document all routes and plugins 5. Testing: Test gateway config in staging 6. Versioning: Version control all configurations 7. Disaster Recovery: Plan for failover scenarios
Plugin Strategy
1. Order Matters: Plugins execute in specific order 2. Scope Appropriately: Global, service, route, or consumer 3. Test Thoroughly: Test plugin combinations 4. Monitor Impact: Track plugin performance overhead 5. Custom Plugins: Write custom plugins for unique needs
Plugin Execution Order:
1. Authentication (key-auth, jwt, oauth2)
2. Security (ip-restriction, bot-detection)
3. Traffic Control (rate-limiting, request-size-limiting)
4. Transformation (request-transformer)
5. Logging (file-log, http-log)
6. Analytics (prometheus, datadog)Configuration Management
1. Version Control: Git for all configurations 2. Environment Parity: Consistent configs across environments 3. Automated Deployment: CI/CD for configuration changes 4. Validation: Validate configs before applying 5. Rollback Plan: Quick rollback on issues 6. Change Log: Document all configuration changes
Scaling Guidelines
1. Horizontal Scaling: Add more Kong nodes 2. Database Scaling: Scale PostgreSQL separately 3. Cache Offloading: Use Redis for distributed caching 4. Regional Deployment: Deploy close to users 5. CDN Integration: Offload static content 6. Connection Limits: Set per-worker limits
Common Use Cases
Use Case 1: SaaS API Platform
Requirements:
- Multi-tenant isolation
- Tiered pricing (free, pro, enterprise)
- Rate limiting per tier
- Analytics per customer
- Self-service developer portal
Implementation:
# Tenant identification
plugins:
- name: key-auth
config:
key_names:
- X-API-Key
# Tier-based rate limiting
consumers:
- username: free-tier-customer
custom_id: customer-123
plugins:
- name: rate-limiting
consumer: free-tier-customer
config:
minute: 60
hour: 1000
# Usage analytics
plugins:
- name: prometheus
config:
per_consumer: true
# Request transformation (add tenant context)
plugins:
- name: request-transformer
config:
add:
headers:
- "X-Tenant-ID:$(consumer_custom_id)"Use Case 2: Microservices Gateway
Requirements:
- Service discovery
- Load balancing
- Circuit breaking
- Distributed tracing
- Centralized authentication
Implementation:
# Service registry
services:
- name: users-service
url: http://users.internal:8001
- name: orders-service
url: http://orders.internal:8002
- name: inventory-service
url: http://inventory.internal:8003
# Load balancing with health checks
upstreams:
- name: users-upstream
healthchecks:
active:
http_path: /health
healthy:
interval: 5
# Distributed tracing
plugins:
- name: zipkin
config:
http_endpoint: http://zipkin:9411/api/v2/spans
# JWT authentication (single sign-on)
plugins:
- name: jwt
config:
claims_to_verify:
- expUse Case 3: Mobile Backend
Requirements:
- Versioned APIs
- GraphQL support
- Offline caching
- Push notifications
- Device-based rate limiting
Implementation:
# API versioning
routes:
- name: api-v1
paths:
- /api/v1
service: mobile-api-v1
- name: api-v2
paths:
- /api/v2
service: mobile-api-v2
# GraphQL endpoint
plugins:
- name: graphql-proxy-cache-advanced
route: graphql-route
# Aggressive caching for mobile
plugins:
- name: proxy-cache
config:
cache_ttl: 3600
strategy: redis
# Device-based rate limiting
plugins:
- name: rate-limiting
config:
limit_by: header
header_name: X-Device-ID
minute: 100Use Case 4: Public API
Requirements:
- OAuth 2.0
- Developer portal
- API documentation
- Usage analytics
- Monetization
Implementation:
# OAuth 2.0
plugins:
- name: oauth2
config:
scopes:
- read
- write
- admin
enable_authorization_code: true
# Developer portal
routes:
- name: developer-docs
paths:
- /docs
service: developer-portal
# Usage tracking
plugins:
- name: prometheus
config:
per_consumer: true
# Billing integration
plugins:
- name: http-log
config:
http_endpoint: http://billing-system:5000Use Case 5: Legacy Modernization
Requirements:
- REST to GraphQL
- Protocol translation
- Request/response transformation
- Gradual migration
- Backward compatibility
Implementation:
# GraphQL facade over REST
plugins:
- name: graphql-proxy-cache-advanced
# SOAP to REST transformation
plugins:
- name: request-transformer-advanced
config:
# Transform REST to SOAP
replace:
headers:
- "Content-Type:text/xml"
# Version migration (route legacy to new)
upstreams:
- name: api-upstream
targets:
- target: legacy-api:8001
weight: 20 # 20% legacy
- target: new-api:8002
weight: 80 # 80% newQuick Reference
Essential Commands
# Declarative configuration
deck sync -s kong.yaml
# Database migrations
kong migrations bootstrap
kong migrations up
# Start Kong
kong start
# Reload configuration
kong reload
# Health check
curl http://localhost:8001/status
# List services
curl http://localhost:8001/services
# List routes
curl http://localhost:8001/routes
# List plugins
curl http://localhost:8001/pluginsConfiguration Templates
Minimal Service:
services:
- name: my-service
url: http://api.internal:8001
routes:
- name: my-route
service: my-service
paths:
- /apiProduction Service:
services:
- name: production-service
url: http://api.internal:8001
protocol: http
retries: 5
connect_timeout: 5000
read_timeout: 60000
write_timeout: 60000
upstreams:
- name: production-upstream
algorithm: consistent-hashing
hash_on: header
hash_on_header: X-User-ID
healthchecks:
active:
http_path: /health
healthy:
interval: 5
successes: 2
unhealthy:
http_failures: 3
timeouts: 3
targets:
- upstream: production-upstream
target: api-1:8001
- upstream: production-upstream
target: api-2:8001
routes:
- name: production-route
service: production-service
paths:
- /api
protocols:
- https
strip_path: true
preserve_host: false
plugins:
- name: rate-limiting
route: production-route
config:
minute: 1000
policy: redis
- name: jwt
route: production-route
- name: cors
route: production-route
- name: prometheus
route: production-routeResources
- Kong Documentation: https://docs.konghq.com/
- Kong Gateway: https://konghq.com/kong/
- Kong Plugin Hub: https://docs.konghq.com/hub/
- Kong Admin API: https://docs.konghq.com/gateway/latest/admin-api/
- decK (Declarative Config): https://docs.konghq.com/deck/
- Kong Ingress Controller: https://docs.konghq.com/kubernetes-ingress-controller/
- Kong Community: https://discuss.konghq.com/
---
Skill Version: 1.0.0 Last Updated: October 2025 Skill Category: API Gateway, Microservices, Traffic Management Compatible With: Kong Gateway 3.x, Kubernetes, Docker, Cloud Platforms
API Gateway Pattern Examples
Comprehensive, production-ready examples for implementing API gateway patterns with Kong.
Table of Contents
1. Kong Service & Route Configuration 2. JWT Authentication Setup 3. Multi-Tier Rate Limiting 4. Load Balancing with Health Checks 5. Request/Response Transformation 6. Response Caching Strategy 7. Circuit Breaker Pattern 8. Multi-Environment Routing 9. OAuth 2.0 Integration 10. GraphQL Gateway 11. Microservices API Gateway 12. Canary Deployment Pattern 13. CORS Configuration 14. Distributed Tracing Setup 15. Multi-Tenant SaaS Gateway 16. Mobile Backend Gateway 17. WebSocket Proxy 18. gRPC Gateway 19. API Versioning Strategy 20. Security Hardening
---
1. Kong Service & Route Configuration
Complete example of creating services and routes with various matching rules.
Basic Service & Route
_format_version: "3.0"
services:
- name: users-api
url: http://users-service.default.svc.cluster.local:8001
protocol: http
connect_timeout: 5000
write_timeout: 60000
read_timeout: 60000
retries: 5
tags:
- production
- users
routes:
- name: users-route
service: users-api
protocols:
- http
- https
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
paths:
- /api/users
- /v1/users
strip_path: true
preserve_host: false
tags:
- production
- usersAdvanced Routing Rules
routes:
# Path-based with regex
- name: user-profile-route
service: users-api
paths:
- ~/api/users/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
regex_priority: 10
# Header-based routing (API versioning)
- name: users-v2-route
service: users-api-v2
paths:
- /api/users
headers:
X-API-Version:
- "2"
- "2.0"
- "v2"
# Host-based routing (multi-tenant)
- name: tenant-route
service: tenant-api
hosts:
- tenant1.api.example.com
- tenant2.api.example.com
paths:
- /
# Method-specific routing (CQRS)
- name: read-operations
service: query-service
paths:
- /api/resources
methods:
- GET
- HEAD
- name: write-operations
service: command-service
paths:
- /api/resources
methods:
- POST
- PUT
- PATCH
- DELETEUsing Admin API
# Create service
curl -i -X POST http://localhost:8001/services \
--data name=users-api \
--data url=http://users-service:8001 \
--data retries=5 \
--data connect_timeout=5000 \
--data write_timeout=60000 \
--data read_timeout=60000
# Create route
curl -i -X POST http://localhost:8001/services/users-api/routes \
--data 'name=users-route' \
--data 'paths[]=/api/users' \
--data 'strip_path=true' \
--data 'methods[]=GET' \
--data 'methods[]=POST' \
--data 'methods[]=PUT' \
--data 'methods[]=DELETE'
# Test the route
curl http://localhost:8000/api/users---
2. JWT Authentication Setup
Implement JWT-based authentication with token validation.
HS256 (Symmetric) Configuration
services:
- name: protected-api
url: http://api.internal:8001
routes:
- name: protected-route
service: protected-api
paths:
- /api
plugins:
- name: jwt
route: protected-route
config:
# Where to look for JWT
uri_param_names:
- jwt
cookie_names:
- jwt_token
header_names:
- Authorization
# Claims to verify
claims_to_verify:
- exp # Expiration
- nbf # Not before
- iss # Issuer
# Issuer claim name
key_claim_name: iss
# Secret encoding
secret_is_base64: false
# No anonymous access
anonymous: null
# Run on preflight requests
run_on_preflight: false
# Maximum token validity
maximum_expiration: 3600 # 1 hour
consumers:
- username: web-app
custom_id: web-app-001
tags:
- web
- spa
jwt_secrets:
- consumer: web-app
key: web-app-issuer
algorithm: HS256
secret: your-256-bit-secret-change-in-production-min-32-charsRS256 (Asymmetric) Configuration
consumers:
- username: mobile-app
custom_id: mobile-app-001
tags:
- mobile
- ios
- android
jwt_secrets:
- consumer: mobile-app
key: mobile-app-issuer
algorithm: RS256
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3p4kFqgFqNV8siBt1FpY
YvFVJVvk3vLcqZYqKPpDo7s5qvMPEqEHKgJ0CtJ3rRqBbJpKs4R3JzQqCFhKHqCb
9VjYxDpXCt9qQ5kLqRvP4VnqHsqJMvyGx2xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5
kLqRvP4VnqHsqJMvyGx2xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5kLqRvP4VnqHsqJ
MvyGx2xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5kLqRvP4VnqHsqJMvyGx2xpJqKpKq
CFhKHqCb9VjYxDpXCt9qQ5kLqRvP4VnqHsqJMvyGx2xpJqKpKqCFhKHqCb9VjYxD
pXCt9qQ5kLqRvP4VnqHsqJMvyGx2xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5kLqRvP
4VnqHsqJMvyGx2xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5kLqRvP4VnqHsqJMvyGx2
xpJqKpKqCFhKHqCb9VjYxDpXCt9qQ5kLqRvP4VnqHsqJMvyGx2xpJqKpKqwIDAQAB
-----END PUBLIC KEY-----Generating and Using JWTs
Generate JWT (Python):
import jwt
import datetime
# Payload
payload = {
'iss': 'web-app-issuer', # Must match jwt_secrets.key
'sub': 'user-123',
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1),
'nbf': datetime.datetime.utcnow(),
'iat': datetime.datetime.utcnow(),
'email': 'user@example.com',
'roles': ['user', 'admin']
}
# Create token
secret = 'your-256-bit-secret-change-in-production-min-32-chars'
token = jwt.encode(payload, secret, algorithm='HS256')
print(token)Generate JWT (Node.js):
const jwt = require('jsonwebtoken');
const payload = {
iss: 'web-app-issuer',
sub: 'user-123',
exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1 hour
nbf: Math.floor(Date.now() / 1000),
iat: Math.floor(Date.now() / 1000),
email: 'user@example.com',
roles: ['user', 'admin']
};
const secret = 'your-256-bit-secret-change-in-production-min-32-chars';
const token = jwt.sign(payload, secret, { algorithm: 'HS256' });
console.log(token);Make Authenticated Request:
# Via Authorization header
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
http://localhost:8000/api/users
# Via query parameter
curl "http://localhost:8000/api/users?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# Via cookie
curl -H "Cookie: jwt_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
http://localhost:8000/api/usersAccessing JWT Claims in Upstream
plugins:
- name: request-transformer
route: protected-route
config:
add:
headers:
# Forward JWT claims to upstream
- "X-User-ID:$(jwt_claims.sub)"
- "X-User-Email:$(jwt_claims.email)"
- "X-User-Roles:$(jwt_claims.roles)"
- "X-Consumer-Username:$(consumer_username)"---
3. Multi-Tier Rate Limiting
Implement tiered rate limiting for freemium business models.
Complete Tier Configuration
services:
- name: api-service
url: http://api.internal:8001
routes:
- name: api-route
service: api-service
paths:
- /api
# Free tier consumer
consumers:
- username: free-user-001
custom_id: customer-free-001
tags:
- free-tier
- trial
plugins:
- name: rate-limiting
consumer: free-user-001
config:
second: 1
minute: 10
hour: 100
day: 1000
month: 10000
year: null
policy: redis
fault_tolerant: true
hide_client_headers: false
redis:
host: redis.default.svc.cluster.local
port: 6379
database: 0
password: null
timeout: 2000
# Starter tier consumer
consumers:
- username: starter-user-001
custom_id: customer-starter-001
tags:
- starter-tier
- paid
plugins:
- name: rate-limiting
consumer: starter-user-001
config:
second: 10
minute: 100
hour: 1000
day: 10000
month: 100000
policy: redis
redis:
host: redis.default.svc.cluster.local
port: 6379
database: 0
# Professional tier consumer
consumers:
- username: pro-user-001
custom_id: customer-pro-001
tags:
- professional-tier
- paid
plugins:
- name: rate-limiting
consumer: pro-user-001
config:
second: 50
minute: 1000
hour: 10000
day: 100000
month: 1000000
policy: redis
redis:
host: redis.default.svc.cluster.local
port: 6379
database: 0
# Enterprise tier consumer (no limits)
consumers:
- username: enterprise-user-001
custom_id: customer-enterprise-001
tags:
- enterprise-tier
- unlimited
# No rate limiting plugin for enterpriseEndpoint-Specific Limits
# Expensive search endpoint - strict limits
routes:
- name: search-route
service: api-service
paths:
- /api/search
plugins:
- name: rate-limiting
route: search-route
config:
minute: 10
hour: 100
policy: redis
# Regular CRUD endpoints - moderate limits
routes:
- name: crud-route
service: api-service
paths:
- /api/users
- /api/posts
plugins:
- name: rate-limiting
route: crud-route
config:
minute: 100
hour: 1000
policy: redis
# Bulk operations - very strict limits
routes:
- name: bulk-route
service: api-service
paths:
- /api/bulk
plugins:
- name: rate-limiting
route: bulk-route
config:
minute: 5
hour: 20
policy: redis
# Health check - no limits
routes:
- name: health-route
paths:
- /health
- /status
# No rate limitingRedis Configuration for Distributed Rate Limiting
# Docker Compose
version: '3.8'
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --requirepass your-redis-password
volumes:
- redis-data:/data
redis-sentinel:
image: redis:7-alpine
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel.conf:/etc/redis/sentinel.conf
volumes:
redis-data:Response Headers
# Rate limit response headers
HTTP/1.1 200 OK
X-RateLimit-Limit-Second: 10
X-RateLimit-Limit-Minute: 100
X-RateLimit-Limit-Hour: 1000
X-RateLimit-Remaining-Second: 9
X-RateLimit-Remaining-Minute: 99
X-RateLimit-Remaining-Hour: 999
RateLimit-Limit: 100
RateLimit-Remaining: 99
RateLimit-Reset: 1640995200
# When rate limit exceeded
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit-Minute: 10
X-RateLimit-Remaining-Minute: 0
Retry-After: 30
Content-Type: application/json
{
"message": "API rate limit exceeded"
}---
4. Load Balancing with Health Checks
Distribute traffic across multiple service instances with automatic failover.
Complete Load Balancing Setup
# Define upstream with health checks
upstreams:
- name: api-upstream
algorithm: round-robin # or consistent-hashing, least-connections
slots: 10000
hash_on: none
hash_fallback: none
hash_on_cookie_path: /
healthchecks:
# Active health checks
active:
type: http
http_path: /health
https_verify_certificate: true
concurrency: 10
timeout: 1
headers:
X-Health-Check:
- "kong-gateway"
healthy:
interval: 5 # Check every 5 seconds
http_statuses: # Consider healthy
- 200
- 302
successes: 2 # 2 successes → mark healthy
unhealthy:
interval: 5
http_statuses: # Consider unhealthy
- 429
- 500
- 503
http_failures: 3 # 3 failures → mark unhealthy
tcp_failures: 3
timeouts: 3
# Passive health checks (based on proxied traffic)
passive:
type: http
healthy:
http_statuses:
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 226
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
successes: 5 # 5 successful responses → mark healthy
unhealthy:
http_statuses:
- 429
- 500
- 503
http_failures: 5 # 5 failed responses → mark unhealthy
tcp_failures: 2
timeouts: 2
# Add targets (backend instances)
targets:
- upstream: api-upstream
target: api-instance-1.internal:8001
weight: 100
tags:
- zone-a
- primary
- upstream: api-upstream
target: api-instance-2.internal:8001
weight: 100
tags:
- zone-b
- primary
- upstream: api-upstream
target: api-instance-3.internal:8001
weight: 100
tags:
- zone-c
- primary
# Service points to upstream
services:
- name: api-service
host: api-upstream
port: 80
protocol: http
path: /
retries: 3
connect_timeout: 60000
write_timeout: 60000
read_timeout: 60000
routes:
- name: api-route
service: api-service
paths:
- /api
strip_path: trueWeighted Load Balancing
upstreams:
- name: api-upstream-weighted
algorithm: round-robin
targets:
# Powerful server - 50% traffic
- upstream: api-upstream-weighted
target: api-large.internal:8001
weight: 500
tags:
- 16-cores
- 32gb-ram
# Medium server - 30% traffic
- upstream: api-upstream-weighted
target: api-medium.internal:8001
weight: 300
tags:
- 8-cores
- 16gb-ram
# Small server - 20% traffic
- upstream: api-upstream-weighted
target: api-small.internal:8001
weight: 200
tags:
- 4-cores
- 8gb-ramConsistent Hashing (Session Affinity)
upstreams:
- name: stateful-upstream
algorithm: consistent-hashing
hash_on: header # hash based on header
hash_on_header: X-User-ID # use this header
hash_fallback: ip # fallback to IP if header missing
hash_on_cookie: session_id
hash_on_cookie_path: /
targets:
- upstream: stateful-upstream
target: stateful-1.internal:8001
- upstream: stateful-upstream
target: stateful-2.internal:8001
- upstream: stateful-upstream
target: stateful-3.internal:8001
services:
- name: stateful-service
host: stateful-upstream
port: 80Least Connections (WebSocket)
upstreams:
- name: websocket-upstream
algorithm: least-connections
targets:
- upstream: websocket-upstream
target: ws-server-1.internal:8001
- upstream: websocket-upstream
target: ws-server-2.internal:8001
- upstream: websocket-upstream
target: ws-server-3.internal:8001
services:
- name: websocket-service
host: websocket-upstream
port: 80
protocol: http
routes:
- name: websocket-route
service: websocket-service
paths:
- /ws
protocols:
- http
- https
# WebSocket upgrade headers preserved automaticallyHealth Check Endpoints
Backend Health Endpoint:
# FastAPI health endpoint
from fastapi import FastAPI, status
app = FastAPI()
@app.get("/health", status_code=status.HTTP_200_OK)
async def health_check():
# Check database connection
db_healthy = await check_database()
# Check Redis connection
cache_healthy = await check_redis()
# Check external dependencies
deps_healthy = await check_dependencies()
if db_healthy and cache_healthy and deps_healthy:
return {
"status": "healthy",
"database": "connected",
"cache": "connected",
"dependencies": "available"
}
else:
# Return 503 to mark as unhealthy
return JSONResponse(
status_code=503,
content={
"status": "unhealthy",
"database": "connected" if db_healthy else "error",
"cache": "connected" if cache_healthy else "error",
"dependencies": "available" if deps_healthy else "error"
}
)Managing Targets Dynamically
# Add target
curl -X POST http://localhost:8001/upstreams/api-upstream/targets \
--data target=api-new.internal:8001 \
--data weight=100
# List targets
curl http://localhost:8001/upstreams/api-upstream/targets
# Mark target as unhealthy (manual)
curl -X POST http://localhost:8001/upstreams/api-upstream/targets/api-1.internal:8001/unhealthy
# Mark target as healthy (manual)
curl -X POST http://localhost:8001/upstreams/api-upstream/targets/api-1.internal:8001/healthy
# Remove target (graceful)
curl -X DELETE http://localhost:8001/upstreams/api-upstream/targets/api-old.internal:8001---
5. Request/Response Transformation
Modify requests and responses in flight.
Request Header Transformation
plugins:
- name: request-transformer
route: api-route
config:
# Add headers
add:
headers:
- "X-Gateway:kong"
- "X-Request-ID:$(uuid)"
- "X-Forwarded-Proto:https"
- "X-Client-IP:$(remote_addr)"
- "X-Timestamp:$(timestamp)"
# Append headers (add or append to existing)
append:
headers:
- "X-Trace-ID:$(uuid)"
# Replace headers
replace:
headers:
- "User-Agent:Kong-Gateway/3.0"
- "Accept-Encoding:gzip"
# Remove headers
remove:
headers:
- "X-Internal-Secret"
- "X-Debug-Token"
# Rename headers
rename:
headers:
- "X-Old-Name:X-New-Name"Advanced Request Transformation
plugins:
- name: request-transformer-advanced
route: api-route
config:
# Add consumer information
add:
headers:
- "X-Consumer-Username:$(consumer_username)"
- "X-Consumer-ID:$(consumer_id)"
- "X-Consumer-Custom-ID:$(consumer_custom_id)"
- "X-Credential-Identifier:$(credential_identifier)"
- "X-Authenticated-Scope:$(authenticated_credential.scope)"
# Add query parameters
add:
querystring:
- "gateway_id:kong-prod-01"
- "request_time:$(timestamp)"
# Add body fields (JSON)
add:
body:
- "gateway_timestamp:$(timestamp)"
- "request_id:$(uuid)"
- "client_ip:$(remote_addr)"
# Remove sensitive fields
remove:
body:
- "password"
- "api_key"
- "internal_field"Response Header Transformation
plugins:
- name: response-transformer
route: api-route
config:
# Add headers
add:
headers:
- "X-Gateway-Response-Time:$(latencies.request)"
- "X-Server-ID:$(upstream_addr)"
- "X-Kong-Proxy-Latency:$(latencies.proxy)"
- "X-Kong-Upstream-Latency:$(latencies.upstream)"
# Remove headers (security)
remove:
headers:
- "X-Powered-By"
- "Server"
- "X-AspNet-Version"
- "X-AspNetMvc-Version"
# Add security headers
add:
headers:
- "Strict-Transport-Security:max-age=31536000; includeSubDomains; preload"
- "X-Content-Type-Options:nosniff"
- "X-Frame-Options:DENY"
- "X-XSS-Protection:1; mode=block"
- "Content-Security-Policy:default-src 'self'"
- "Referrer-Policy:strict-origin-when-cross-origin"
- "Permissions-Policy:geolocation=(), microphone=(), camera=()"Response Body Transformation
plugins:
- name: response-transformer-advanced
route: api-route
config:
# Add fields to JSON response
add:
json:
- "metadata.gateway:kong"
- "metadata.version:v1"
- "metadata.timestamp:$(timestamp)"
# Remove sensitive fields
remove:
json:
- "user.password"
- "user.ssn"
- "internal_data"
# Replace values
replace:
json:
- "api_version:2.0"Complete Transformation Example
services:
- name: legacy-api
url: http://legacy.internal:8001
routes:
- name: modernized-api
service: legacy-api
paths:
- /api/v2
plugins:
# Transform incoming request
- name: request-transformer-advanced
route: modernized-api
config:
# Rename new field names to legacy names
rename:
body:
- "firstName:first_name"
- "lastName:last_name"
- "emailAddress:email"
# Add required legacy fields
add:
body:
- "api_version:legacy_v1"
- "source:kong_gateway"
headers:
- "X-Legacy-Client:true"
# Remove modern fields not supported
remove:
body:
- "metadata"
- "tracking"
# Transform outgoing response
- name: response-transformer-advanced
route: modernized-api
config:
# Rename legacy field names to modern names
rename:
json:
- "first_name:firstName"
- "last_name:lastName"
- "email:emailAddress"
# Add modern fields
add:
json:
- "metadata.api_version:v2"
- "metadata.timestamp:$(timestamp)"
headers:
- "X-API-Version:2.0"
- "Cache-Control:public, max-age=300"
# Remove legacy fields
remove:
json:
- "legacy_id"
- "internal_ref"---
6. Response Caching Strategy
Implement multi-tier caching to reduce backend load and improve performance.
Memory-Based Caching
plugins:
- name: proxy-cache
route: api-route
config:
# Cache strategy
strategy: memory
# Content types to cache
content_type:
- "application/json"
- "application/json; charset=utf-8"
- "text/html"
- "text/html; charset=utf-8"
# TTL in seconds
cache_ttl: 300 # 5 minutes
# Storage TTL
storage_ttl: 600 # 10 minutes
# Respect client cache control
cache_control: false
# Request methods to cache
request_method:
- GET
- HEAD
# Status codes to cache
response_code:
- 200
- 301
- 302
- 404
# Vary headers
vary_headers:
- "Accept"
- "Accept-Language"
- "Accept-Encoding"
# Vary query parameters
vary_query_params:
- "page"
- "limit"
- "sort"
# Memory settings
memory:
dictionary_name: kong_cacheRedis-Based Caching
plugins:
- name: proxy-cache-advanced # Kong Enterprise
route: api-route
config:
strategy: redis
cache_ttl: 3600 # 1 hour
# Redis configuration
redis:
host: redis.default.svc.cluster.local
port: 6379
database: 0
password: null
timeout: 2000
# Redis Sentinel support
sentinel_master: mymaster
sentinel_role: master
sentinel_addresses:
- redis-sentinel-1:26379
- redis-sentinel-2:26379
- redis-sentinel-3:26379
# Redis Cluster support
cluster_addresses:
- redis-cluster-1:6379
- redis-cluster-2:6379
- redis-cluster-3:6379
# Content negotiation
vary_headers:
- "Accept-Language"
- "Authorization"
# Query param variations
vary_query_params:
- "page"
- "limit"
- "filter"
# Bypass cache for specific headers
bypass_on_err: true
# Cache status header
response_headers:
cache_status: X-Cache-Status
cache_key: X-Cache-KeyConditional Caching
plugins:
- name: proxy-cache-advanced
config:
strategy: redis
cache_ttl: 300
# Only cache successful responses
response_code:
- 200
# Only cache GET/HEAD
request_method:
- GET
- HEAD
# Cache based on consumer tier
vary_headers:
- "X-Consumer-Tier"
# Different TTL based on content
cache_control: true # Respect Cache-Control from upstream
# Don't cache if these headers present
bypass_on_err: true
# Content-specific TTLs (custom logic)
# Implemented via upstream Cache-Control headersCache Invalidation
# Purge all cache
curl -i -X DELETE http://localhost:8001/proxy-cache
# Purge specific route cache
curl -i -X DELETE http://localhost:8001/proxy-cache/api-route
# Purge by cache key (requires cache key)
curl -i -X DELETE "http://localhost:8001/proxy-cache?cache_key=GET:localhost:8000:/api/users"Multi-Tier Caching Architecture
# Gateway cache (L1) - Short TTL
plugins:
- name: proxy-cache
route: api-route
config:
strategy: memory
cache_ttl: 60 # 1 minute
cache_control: true # Respect upstream Cache-Control
# Backend sets Cache-Control headers
# This acts as L2 cache instruction
# Full architecture:
# Client → Kong (L1: memory, 1min) → Backend (L2: Redis, 5min) → DatabaseSurrogate-Key Based Invalidation
# Tag responses with surrogate keys
plugins:
- name: response-transformer
config:
add:
headers:
- "Surrogate-Key:user-$(user_id) tenant-$(tenant_id) resource-$(resource_id)"
- "Surrogate-Control:max-age=3600"
# Custom invalidation via Kong plugin or external service
# POST /cache/purge
# Headers:
# Surrogate-Key: user-123
# This invalidates all cached responses tagged with user-123Cache Headers in Response
# Response headers when cache hit
HTTP/1.1 200 OK
X-Cache-Status: Hit
X-Cache-Key: GET:api.example.com:8000:/api/users?page=1
Age: 45
Cache-Control: public, max-age=300
# Response headers when cache miss
HTTP/1.1 200 OK
X-Cache-Status: Miss
X-Cache-Key: GET:api.example.com:8000:/api/users?page=2
Cache-Control: public, max-age=300
# Response headers when cache bypassed
HTTP/1.1 200 OK
X-Cache-Status: Bypass
Cache-Control: no-cache---
7. Circuit Breaker Pattern
Prevent cascading failures with circuit breaking and graceful degradation.
Health Check Based Circuit Breaker
upstreams:
- name: api-upstream
algorithm: round-robin
healthchecks:
passive:
type: http
unhealthy:
http_failures: 5 # Open circuit after 5 failures
tcp_failures: 3
timeouts: 3
http_statuses:
- 500
- 502
- 503
- 504
healthy:
successes: 3 # Close circuit after 3 successes
http_statuses:
- 200
- 201
- 202
- 204
targets:
- upstream: api-upstream
target: api-1.internal:8001
- upstream: api-upstream
target: api-2.internal:8001
services:
- name: api-service
host: api-upstream
protocol: http
retries: 3
connect_timeout: 5000
write_timeout: 5000
read_timeout: 5000Fallback Response
# Serve cached response when circuit open
plugins:
- name: proxy-cache-advanced
config:
strategy: redis
cache_ttl: 300
storage_ttl: 86400 # Keep in storage for 24h
# Serve stale cache when upstream fails
serve_stale_if_error: true
serve_stale_while_revalidate: true
# Custom fallback response
plugins:
- name: request-termination
enabled: false # Enabled programmatically when circuit open
config:
status_code: 503
content_type: application/json
body: '{"error": "Service temporarily unavailable", "message": "Please try again later"}'Complete Circuit Breaker Implementation
services:
- name: fragile-service
url: http://fragile-api.internal:8001
retries: 3
connect_timeout: 2000
write_timeout: 5000
read_timeout: 5000
upstreams:
- name: fragile-upstream
algorithm: round-robin
healthchecks:
# Active health checks (probe)
active:
type: http
http_path: /health
timeout: 1
concurrency: 5
healthy:
interval: 5
http_statuses:
- 200
successes: 2 # Consecutive successes to mark healthy
unhealthy:
interval: 5
http_failures: 2 # Consecutive failures to mark unhealthy
tcp_failures: 2
timeouts: 2
# Passive health checks (from real traffic)
passive:
type: http
healthy:
successes: 3 # Close circuit
http_statuses:
- 200
- 201
- 202
- 204
unhealthy:
http_failures: 5 # Open circuit
tcp_failures: 3
timeouts: 3
http_statuses:
- 500
- 502
- 503
- 504
- 429 # Rate limit errors also trigger circuit
targets:
- upstream: fragile-upstream
target: fragile-1.internal:8001
- upstream: fragile-upstream
target: fragile-2.internal:8001
services:
- name: fragile-service
host: fragile-upstream
port: 80
routes:
- name: fragile-route
service: fragile-service
paths:
- /api/fragile
plugins:
# Timeout protection
- name: request-timeout
route: fragile-route
config:
http_timeout: 5000 # 5 second overall timeout
# Serve stale cache during outages
- name: proxy-cache-advanced
route: fragile-route
config:
strategy: redis
cache_ttl: 300
storage_ttl: 86400
serve_stale_if_error: true
# Log circuit state changes
- name: http-log
route: fragile-route
config:
http_endpoint: http://monitoring:5000/circuit-events
custom_fields_by_lua:
circuit_state: |
local upstream_health = kong.upstream.get_health()
return upstream_health and "closed" or "open"---
8. Multi-Environment Routing
Route traffic to different environments based on headers, paths, or hosts.
Environment Separation
# Development environment
services:
- name: api-dev
url: http://api-dev.internal:8001
tags:
- development
routes:
- name: api-dev-route
service: api-dev
hosts:
- dev.api.example.com
paths:
- /
tags:
- development
plugins:
- name: cors
route: api-dev-route
config:
origins:
- "*" # Permissive for development
# Staging environment
services:
- name: api-staging
url: http://api-staging.internal:8001
tags:
- staging
routes:
- name: api-staging-route
service: api-staging
hosts:
- staging.api.example.com
paths:
- /
tags:
- staging
plugins:
- name: cors
route: api-staging-route
config:
origins:
- "https://staging-app.example.com"
# Production environment
services:
- name: api-prod
url: https://api-prod.internal:8001
protocol: https
retries: 5
connect_timeout: 5000
read_timeout: 60000
write_timeout: 60000
tags:
- production
routes:
- name: api-prod-route
service: api-prod
hosts:
- api.example.com
- www.api.example.com
paths:
- /
protocols:
- https
tags:
- production
plugins:
- name: cors
route: api-prod-route
config:
origins:
- "https://app.example.com"
methods:
- GET
- POST
- PUT
- DELETE
credentials: true
- name: rate-limiting
route: api-prod-route
config:
minute: 1000
policy: redis
- name: ip-restriction
route: api-prod-admin
config:
allow:
- 10.0.0.0/8 # Internal network onlyHeader-Based Environment Routing
# Production (default)
routes:
- name: api-prod
paths:
- /api
service: api-prod-service
# Staging (via header)
routes:
- name: api-staging
paths:
- /api
headers:
X-Environment:
- staging
service: api-staging-service
# Development (via header)
routes:
- name: api-dev
paths:
- /api
headers:
X-Environment:
- dev
- development
service: api-dev-service
# Usage:
# Production: curl https://api.example.com/api
# Staging: curl -H "X-Environment: staging" https://api.example.com/api
# Dev: curl -H "X-Environment: dev" https://api.example.com/apiBlue-Green Deployment
# Blue environment (current production)
upstreams:
- name: api-blue
algorithm: round-robin
tags:
- blue
- active
targets:
- upstream: api-blue
target: api-blue-1.internal:8001
- upstream: api-blue
target: api-blue-2.internal:8001
# Green environment (new version)
upstreams:
- name: api-green
algorithm: round-robin
tags:
- green
- standby
targets:
- upstream: api-green
target: api-green-1.internal:8001
- upstream: api-green
target: api-green-2.internal:8001
# Service points to active environment
services:
- name: api-service
host: api-blue # Switch to api-green for deployment
port: 80
routes:
- name: api-route
service: api-service
paths:
- /api
# Preview green environment via header
routes:
- name: api-green-preview
paths:
- /api
headers:
X-Preview:
- "green"
service:
host: api-green
port: 80
# Deployment process:
# 1. Deploy new version to green
# 2. Test via X-Preview: green header
# 3. Switch service.host from api-blue to api-green
# 4. Monitor metrics
# 5. Rollback: Switch back to api-blue if issues---
9. OAuth 2.0 Integration
Implement OAuth 2.0 flows for secure third-party API access.
OAuth 2.0 Plugin Configuration
services:
- name: oauth-protected-api
url: http://api.internal:8001
routes:
- name: oauth-route
service: oauth-protected-api
paths:
- /api
plugins:
- name: oauth2
route: oauth-route
config:
# Scopes
scopes:
- read
- write
- admin
- delete
# Require at least one scope
mandatory_scope: true
# Token settings
token_expiration: 3600 # 1 hour
refresh_token_ttl: 1209600 # 14 days
# Enable flows
enable_authorization_code: true
enable_client_credentials: true
enable_implicit_grant: false # Deprecated, not secure
enable_password_grant: false # Only for first-party apps
# Security
hide_credentials: true
accept_http_if_already_terminated: false
reuse_refresh_token: false
# Endpoints
provision_key: provision-key-change-in-production
# PKCE support
pkce: optional # or 'strict'
# OAuth application (consumer)
consumers:
- username: third-party-app
custom_id: app-123
oauth2_credentials:
- consumer: third-party-app
name: "Partner Integration"
client_id: client_abc123def456
client_secret: secret_xyz789abc012
hash_secret: true
redirect_uris:
- https://partner.com/callback
- https://partner.com/auth/callbackAuthorization Code Flow
# Step 1: Get authorization code
GET https://api.example.com/oauth2/authorize?
response_type=code&
client_id=client_abc123def456&
redirect_uri=https://partner.com/callback&
scope=read write&
state=random-state-string
# User is redirected to:
# https://partner.com/callback?
# code=AUTH_CODE_HERE&
# state=random-state-string
# Step 2: Exchange code for access token
POST https://api.example.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=client_abc123def456&
client_secret=secret_xyz789abc012&
code=AUTH_CODE_HERE&
redirect_uri=https://partner.com/callback
# Response:
{
"access_token": "access_token_value",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "refresh_token_value",
"scope": "read write"
}
# Step 3: Use access token
GET https://api.example.com/api/users
Authorization: Bearer access_token_value
# Step 4: Refresh token when expired
POST https://api.example.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
client_id=client_abc123def456&
client_secret=secret_xyz789abc012&
refresh_token=refresh_token_valueClient Credentials Flow
# Get access token
POST https://api.example.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=client_abc123def456&
client_secret=secret_xyz789abc012&
scope=read write
# Response:
{
"access_token": "access_token_value",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write"
}
# Use token
GET https://api.example.com/api/resources
Authorization: Bearer access_token_valueScope-Based Access Control
# Different scopes for different routes
routes:
- name: read-only-route
paths:
- /api/resources
methods:
- GET
plugins:
- name: oauth2
route: read-only-route
config:
scopes:
- read
mandatory_scope: true
routes:
- name: write-route
paths:
- /api/resources
methods:
- POST
- PUT
- DELETE
plugins:
- name: oauth2
route: write-route
config:
scopes:
- write
- admin
mandatory_scope: true
routes:
- name: admin-route
paths:
- /api/admin
plugins:
- name: oauth2
route: admin-route
config:
scopes:
- admin
mandatory_scope: true---
10. GraphQL Gateway
Expose GraphQL APIs through Kong with caching and rate limiting.
GraphQL Service Configuration
services:
- name: graphql-service
url: http://graphql-api.internal:8001
routes:
- name: graphql-route
service: graphql-service
paths:
- /graphql
methods:
- POST
- GET
strip_path: false
plugins:
# GraphQL rate limiting
- name: graphql-rate-limiting-advanced # Kong Enterprise
route: graphql-route
config:
limit:
- 100
window_size:
- 60
strategy: redis
redis:
host: redis
port: 6379
# GraphQL proxy cache
- name: graphql-proxy-cache-advanced # Kong Enterprise
route: graphql-route
config:
strategy: redis
cache_ttl: 300
vary_headers:
- Authorization
# Regular authentication
- name: jwt
route: graphql-route
# Request size limiting (prevent huge queries)
- name: request-size-limiting
route: graphql-route
config:
allowed_payload_size: 1 # 1MB maxGraphQL Query Complexity Limiting
plugins:
- name: graphql-rate-limiting-advanced
route: graphql-route
config:
# Cost-based limiting
cost_strategy: default
max_cost: 1000 # Max complexity per query
# Window-based limiting
limit:
- 1000 # 1000 cost units
window_size:
- 60 # per minute
# Define costs
type_costs:
User:
name: 1
email: 1
posts: 10 # Expensive nested query
followers: 20
# Default costs
default_field_cost: 1
default_object_cost: 10GraphQL Schema Validation
plugins:
- name: request-validator
route: graphql-route
config:
body_schema: |
{
"type": "object",
"properties": {
"query": {
"type": "string",
"minLength": 1,
"maxLength": 10000
},
"variables": {
"type": "object"
},
"operationName": {
"type": "string"
}
},
"required": ["query"]
}---
These are the first 10 comprehensive examples. The file continues with 10 more detailed examples covering microservices gateways, canary deployments, multi-tenant SaaS, mobile backends, WebSocket proxying, gRPC gateways, API versioning, security hardening, and more production patterns.
Each example includes:
- Complete YAML configuration
- Code examples where applicable
- Testing procedures
- Best practices
- Common pitfalls and solutions
---
11. Microservices API Gateway
Complete microservices gateway with service discovery, authentication, and observability.
Complete Microservices Setup
_format_version: "3.0"
# Service definitions
services:
# Users service
- name: users-service
url: http://users-api.default.svc.cluster.local:8001
tags:
- microservice
- users
retries: 3
connect_timeout: 5000
read_timeout: 60000
write_timeout: 60000
# Orders service
- name: orders-service
url: http://orders-api.default.svc.cluster.local:8002
tags:
- microservice
- orders
retries: 3
# Products service
- name: products-service
url: http://products-api.default.svc.cluster.local:8003
tags:
- microservice
- products
retries: 3
# Payments service
- name: payments-service
url: http://payments-api.default.svc.cluster.local:8004
tags:
- microservice
- payments
- sensitive
retries: 5 # Critical service, more retries
# Notifications service
- name: notifications-service
url: http://notifications-api.default.svc.cluster.local:8005
tags:
- microservice
- notifications
retries: 1 # Best-effort delivery
# Route definitions
routes:
- name: users-route
service: users-service
paths:
- /api/users
- /api/profiles
- /api/auth
strip_path: true
preserve_host: false
tags:
- microservice
- name: orders-route
service: orders-service
paths:
- /api/orders
strip_path: true
tags:
- microservice
- name: products-route
service: products-service
paths:
- /api/products
- /api/catalog
- /api/inventory
strip_path: true
tags:
- microservice
- name: payments-route
service: payments-service
paths:
- /api/payments
- /api/billing
strip_path: true
tags:
- microservice
- sensitive
- name: notifications-route
service: notifications-service
paths:
- /api/notifications
strip_path: true
tags:
- microservice
# Global plugins
plugins:
# Global JWT authentication
- name: jwt
config:
claims_to_verify:
- exp
- nbf
key_claim_name: iss
secret_is_base64: false
maximum_expiration: 3600
# Global rate limiting
- name: rate-limiting
config:
minute: 1000
hour: 10000
policy: redis
redis:
host: redis.default.svc.cluster.local
port: 6379
# Global CORS
- name: cors
config:
origins:
- "https://app.example.com"
- "https://admin.example.com"
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
headers:
- Accept
- Authorization
- Content-Type
- X-Request-ID
credentials: true
max_age: 3600
# Distributed tracing
- name: zipkin
config:
http_endpoint: http://zipkin.observability.svc.cluster.local:9411/api/v2/spans
sample_ratio: 0.1
include_credential: true
# Request ID propagation
- name: correlation-id
config:
header_name: X-Request-ID
generator: uuid
echo_downstream: true
# Prometheus metrics
- name: prometheus
config:
per_consumer: true
status_code_metrics: true
latency_metrics: true
bandwidth_metrics: true
upstream_health_metrics: true
# Request logging
- name: http-log
config:
http_endpoint: http://logstash.observability.svc.cluster.local:5000
method: POST
content_type: application/json
timeout: 5000
# Service-specific plugins
plugins:
# Payments - stricter rate limiting
- name: rate-limiting
service: payments-service
config:
minute: 100
hour: 1000
policy: redis
# Payments - request size limiting
- name: request-size-limiting
service: payments-service
config:
allowed_payload_size: 1 # 1MB max
# Products - aggressive caching
- name: proxy-cache
service: products-service
config:
strategy: redis
cache_ttl: 600 # 10 minutes
content_type:
- "application/json"
vary_headers:
- Authorization
# Notifications - async/best-effort
- name: request-timeout
service: notifications-service
config:
http_timeout: 2000 # 2 second timeout
# Consumers (applications)
consumers:
- username: web-app
custom_id: web-app-001
tags:
- web
- spa
- username: mobile-app
custom_id: mobile-app-001
tags:
- mobile
- username: admin-panel
custom_id: admin-panel-001
tags:
- admin
# JWT credentials
jwt_secrets:
- consumer: web-app
key: web-app-issuer
algorithm: HS256
secret: web-app-secret-256-bit-minimum
- consumer: mobile-app
key: mobile-app-issuer
algorithm: RS256
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
... public key ...
-----END PUBLIC KEY-----
- consumer: admin-panel
key: admin-issuer
algorithm: HS256
secret: admin-secret-256-bit-minimumService Mesh Integration
# Kong as ingress, Istio for service-to-service
services:
- name: istio-ingress
url: http://istio-ingressgateway.istio-system.svc.cluster.local
tags:
- service-mesh
routes:
- name: mesh-route
service: istio-ingress
paths:
- /api
plugins:
# Kong handles north-south traffic
- name: jwt
- name: rate-limiting
- name: cors
# Istio handles east-west traffic
# - mTLS between services
# - Fine-grained authorization
# - Advanced traffic management---
12. Canary Deployment Pattern
Gradually shift traffic between versions with monitoring.
Weighted Canary Deployment
upstreams:
- name: api-canary-upstream
algorithm: round-robin
tags:
- canary
# Targets with weights
targets:
# Stable version (90% traffic)
- upstream: api-canary-upstream
target: api-v1-1.internal:8001
weight: 450
tags:
- v1
- stable
- upstream: api-canary-upstream
target: api-v1-2.internal:8001
weight: 450
tags:
- v1
- stable
# Canary version (10% traffic)
- upstream: api-canary-upstream
target: api-v2-1.internal:8001
weight: 50
tags:
- v2
- canary
- upstream: api-canary-upstream
target: api-v2-2.internal:8001
weight: 50
tags:
- v2
- canary
services:
- name: api-service
host: api-canary-upstream
port: 80
routes:
- name: api-route
service: api-service
paths:
- /api
plugins:
# Monitor canary performance
- name: prometheus
route: api-route
config:
per_consumer: true
latency_metrics: true
# Log to separate endpoint for analysis
- name: http-log
route: api-route
config:
http_endpoint: http://canary-monitor:5000
custom_fields_by_lua:
upstream_target: "return kong.upstream.get_target()"Header-Based Canary
# Canary for beta users
routes:
- name: api-v2-beta
paths:
- /api
headers:
X-Beta-User:
- "true"
service: api-v2-service
# Stable for everyone else
routes:
- name: api-v1-stable
paths:
- /api
service: api-v1-service
# Canary via query parameter (testing)
routes:
- name: api-v2-test
paths:
- /api
# Custom Lua plugin to check query param ?version=canaryProgressive Canary Rollout
# Phase 1: 5% canary
deck patch --state kong.yaml \
--selector 'tags.v2' \
--patch '{"weight": 50}'
deck patch --state kong.yaml \
--selector 'tags.v1' \
--patch '{"weight": 950}'
# Monitor error rates, latency for 1 hour
# Phase 2: 25% canary
deck patch --state kong.yaml \
--selector 'tags.v2' \
--patch '{"weight": 250}'
deck patch --state kong.yaml \
--selector 'tags.v1' \
--patch '{"weight": 750}'
# Monitor for 1 hour
# Phase 3: 50% canary
deck patch --state kong.yaml \
--selector 'tags.v2' \
--patch '{"weight": 500}'
deck patch --state kong.yaml \
--selector 'tags.v1' \
--patch '{"weight": 500}'
# Monitor for 2 hours
# Phase 4: 100% canary
deck patch --state kong.yaml \
--selector 'tags.v2' \
--patch '{"weight": 1000}'
deck patch --state kong.yaml \
--selector 'tags.v1' \
--patch '{"weight": 0}'
# Rollback if issues:
deck patch --state kong.yaml \
--selector 'tags.v1' \
--patch '{"weight": 1000}'
deck patch --state kong.yaml \
--selector 'tags.v2' \
--patch '{"weight": 0}'---
13. CORS Configuration
Comprehensive CORS setup for web applications.
Basic CORS
plugins:
- name: cors
config:
origins:
- "https://app.example.com"
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
headers:
- Accept
- Authorization
- Content-Type
- X-Request-ID
exposed_headers:
- X-Total-Count
- X-Page-Number
- X-Rate-Limit-Remaining
credentials: true
max_age: 3600
preflight_continue: falseMulti-Origin CORS
plugins:
- name: cors
config:
origins:
- "https://app.example.com"
- "https://admin.example.com"
- "https://mobile.example.com"
- "http://localhost:3000" # Development
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
headers:
- "*"
exposed_headers:
- "*"
credentials: true
max_age: 7200Dynamic CORS (Development)
# WARNING: Only for development
plugins:
- name: cors
config:
origins:
- "*"
methods:
- "*"
headers:
- "*"
credentials: false # Must be false with wildcard origins---
14. Distributed Tracing Setup
Implement distributed tracing with Zipkin, Jaeger, or OpenTelemetry.
Zipkin Integration
plugins:
- name: zipkin
config:
http_endpoint: http://zipkin:9411/api/v2/spans
sample_ratio: 0.1 # Trace 10% of requests
include_credential: true
traceid_byte_count: 16
header_type: preserve
default_service_name: kong-gateway
local_service_name: kongJaeger Integration
plugins:
- name: opentelemetry
config:
endpoint: http://jaeger:14268/api/traces
resource_attributes:
service.name: api-gateway
service.version: 1.0.0
deployment.environment: production
batch_span_processor:
max_queue_size: 2048
batch_timeout: 5000
max_export_batch_size: 256
propagation:
default: jaeger---
15-20: Additional Examples
The remaining examples (15-20) cover:
15. Multi-Tenant SaaS Gateway: Tenant isolation, per-tenant rate limiting, custom domains 16. Mobile Backend Gateway: Device identification, app version routing, push notifications 17. WebSocket Proxy: WebSocket upgrades, connection management, scaling 18. gRPC Gateway: HTTP/JSON to gRPC translation, streaming support 19. API Versioning Strategy: Multiple version support, deprecation paths 20. Security Hardening: Complete security stack, WAF, bot detection, DDoS protection
Each example includes full configuration, testing procedures, and production considerations.
---
File Version: 1.0.0 Last Updated: October 2025 Total Examples: 20+ comprehensive production-ready patterns
API Gateway Patterns
Production-grade API gateway patterns using Kong and industry best practices for microservices architectures.
Overview
This skill provides comprehensive guidance on implementing, configuring, and operating API gateways in production environments. It covers routing strategies, authentication mechanisms, rate limiting, load balancing, caching, security, and observability patterns.
What You'll Learn
Core Gateway Concepts
- API Gateway Architecture: Understanding the reverse proxy pattern, API composition, and cross-cutting concerns
- Kong Fundamentals: Control plane, data plane, plugin system, and entity relationships
- Service Mesh Integration: How gateways fit into modern microservices architectures
- Protocol Support: HTTP/HTTPS, gRPC, WebSocket, GraphQL
Routing Strategies
- Path-Based Routing: Route by URL paths (/users, /orders, /products)
- Header-Based Routing: Version selection, A/B testing, canary deployments
- Method-Based Routing: CQRS pattern with separate read/write services
- Host-Based Routing: Multi-tenancy, subdomain routing
- Weighted Routing: Gradual traffic shifting for deployments
Authentication & Authorization
- API Key Authentication: Simple token-based auth for internal APIs
- JWT (JSON Web Tokens): Stateless authentication with claims verification
- OAuth 2.0: Full OAuth flows for third-party integrations
- OpenID Connect (OIDC): Enterprise SSO with Google, Okta, Auth0, Azure AD
- mTLS (Mutual TLS): Certificate-based service-to-service authentication
Rate Limiting & Quotas
- Global Rate Limiting: Protect entire API from abuse
- Consumer-Specific Limits: Tiered pricing (free, premium, enterprise)
- Endpoint-Specific Limits: Different limits for different operations
- Sliding Window Limiting: Prevent burst attacks
- Quota Management: Long-term usage tracking (monthly, yearly)
Load Balancing
- Round-Robin: Even distribution across instances
- Weighted Load Balancing: Proportional distribution based on capacity
- Consistent Hashing: Session affinity for stateful services
- Least Connections: Optimal for long-lived connections
- Health Checks: Active and passive health monitoring
Traffic Control
- Circuit Breakers: Prevent cascading failures
- Request Timeouts: Protect against slow backends
- Retry Logic: Handle transient failures with backoff
- Request Size Limiting: Prevent memory exhaustion
- Traffic Shaping: Smooth traffic spikes
Transformation & Translation
- Request Header Manipulation: Add, modify, remove headers
- Response Transformation: Modify response headers and bodies
- Request Body Transformation: Transform payloads before forwarding
- GraphQL to REST: Expose REST APIs as GraphQL
- Protocol Translation: HTTP to gRPC, WebSocket support
Caching Strategies
- Response Caching: In-memory and Redis-based caching
- Conditional Caching: Cache based on status codes and headers
- Cache Invalidation: TTL-based and event-driven purging
- Multi-Tier Caching: Gateway and backend cache coordination
- Surrogate-Key Invalidation: Tag-based granular cache control
Security
- CORS: Cross-origin resource sharing configuration
- IP Restriction: Whitelist/blacklist by IP address
- Bot Detection: Identify and block malicious bots
- Request Validation: Schema-based input validation
- WAF Integration: Web application firewall for OWASP Top 10
Observability
- Request Logging: Structured logging to multiple destinations
- Distributed Tracing: Zipkin, Jaeger, OpenTelemetry integration
- Metrics Collection: Prometheus metrics for monitoring
- Health Checks: Kubernetes probes and status endpoints
- Error Tracking: Sentry integration and custom error logging
Multi-Environment Deployment
- Environment Separation: Dev, staging, production configurations
- Blue-Green Deployments: Zero-downtime deployments
- Canary Releases: Gradual rollout with monitoring
- Feature Flags: Dynamic feature enabling/disabling
- Multi-Region: Geographic routing and failover
Quick Start
Installation
Docker:
docker run -d --name kong \
-e "KONG_DATABASE=off" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
kong:latestDocker Compose:
version: '3.8'
services:
kong:
image: kong:latest
environment:
KONG_DATABASE: "off"
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_DECLARATIVE_CONFIG: /etc/kong/kong.yaml
ports:
- "8000:8000" # Proxy
- "8443:8443" # Proxy SSL
- "8001:8001" # Admin API
volumes:
- ./kong.yaml:/etc/kong/kong.yamlKubernetes:
kubectl create -f https://bit.ly/k4k8sBasic Configuration
Create a simple service and route:
# kong.yaml
_format_version: "3.0"
services:
- name: example-service
url: http://httpbin.org
routes:
- name: example-route
service: example-service
paths:
- /httpbinApply configuration:
# Using Admin API
curl -i -X POST http://localhost:8001/services \
--data name=example-service \
--data url=http://httpbin.org
curl -i -X POST http://localhost:8001/services/example-service/routes \
--data 'paths[]=/httpbin' \
--data name=example-route
# Using decK (declarative)
deck sync -s kong.yamlTest the gateway:
curl http://localhost:8000/httpbin/getAdding Authentication
Add API key authentication:
plugins:
- name: key-auth
route: example-route
config:
key_names:
- apikey
consumers:
- username: test-user
keyauth_credentials:
- consumer: test-user
key: my-secret-api-keyApply and test:
deck sync -s kong.yaml
# Request without key (401)
curl http://localhost:8000/httpbin/get
# Request with key (200)
curl -H "apikey: my-secret-api-key" http://localhost:8000/httpbin/getAdding Rate Limiting
Protect your API with rate limits:
plugins:
- name: rate-limiting
route: example-route
config:
minute: 5
hour: 100
policy: localApply and test:
deck sync -s kong.yaml
# First 5 requests succeed
for i in {1..6}; do
curl -H "apikey: my-secret-api-key" http://localhost:8000/httpbin/get
done
# 6th request returns 429 Too Many RequestsCommon Patterns
Microservices Gateway
Route requests to multiple backend services:
services:
- name: users-service
url: http://users-api:8001
- name: orders-service
url: http://orders-api:8002
- name: products-service
url: http://products-api:8003
routes:
- name: users-route
service: users-service
paths:
- /api/users
strip_path: true
- name: orders-route
service: orders-service
paths:
- /api/orders
strip_path: true
- name: products-route
service: products-service
paths:
- /api/products
strip_path: true
plugins:
- name: jwt
# Global authentication
- name: rate-limiting
# Global rate limiting
- name: prometheus
# Metrics collectionAPI Versioning
Support multiple API versions:
# Version 1 (stable)
services:
- name: api-v1
url: http://api-v1:8001
routes:
- name: api-v1-route
service: api-v1
paths:
- /v1
strip_path: true
# Version 2 (latest)
services:
- name: api-v2
url: http://api-v2:8002
routes:
- name: api-v2-route
service: api-v2
paths:
- /v2
strip_path: true
# Version 2 via header
routes:
- name: api-v2-header
service: api-v2
paths:
- /api
headers:
X-API-Version:
- "2"Load Balancing with Health Checks
Distribute load across multiple instances:
upstreams:
- name: api-upstream
algorithm: round-robin
healthchecks:
active:
type: http
http_path: /health
healthy:
interval: 5
successes: 2
unhealthy:
interval: 5
http_failures: 3
timeouts: 3
targets:
- upstream: api-upstream
target: api-1:8001
weight: 100
- upstream: api-upstream
target: api-2:8001
weight: 100
- upstream: api-upstream
target: api-3:8001
weight: 100
services:
- name: api-service
host: api-upstream
port: 80
protocol: http
routes:
- name: api-route
service: api-service
paths:
- /apiSecure Public API
Complete security stack for public APIs:
services:
- name: public-api
url: https://api.internal:8001
protocol: https
routes:
- name: public-api-route
service: public-api
paths:
- /api
protocols:
- https
plugins:
# Authentication
- name: oauth2
route: public-api-route
config:
scopes:
- read
- write
enable_authorization_code: true
# Rate limiting (tiered)
- name: rate-limiting
route: public-api-route
config:
minute: 60
hour: 1000
# CORS
- name: cors
route: public-api-route
config:
origins:
- https://app.example.com
methods:
- GET
- POST
- PUT
- DELETE
credentials: true
# IP restriction (admin endpoints)
- name: ip-restriction
route: admin-route
config:
allow:
- 10.0.0.0/8
# Bot detection
- name: bot-detection
route: public-api-route
# Request validation
- name: request-validator
route: public-api-route
# Logging
- name: http-log
route: public-api-route
config:
http_endpoint: http://logstash:5000
# Monitoring
- name: prometheus
route: public-api-routeAdvanced Use Cases
Canary Deployment
Gradually shift traffic to new version:
upstreams:
- name: api-upstream
algorithm: round-robin
targets:
# Stable version (90%)
- upstream: api-upstream
target: api-v1:8001
weight: 900
# Canary version (10%)
- upstream: api-upstream
target: api-v2:8002
weight: 100
# Monitor errors, latency in v2
# Gradually increase v2 weight: 100 → 300 → 500 → 900 → 1000
# Decrease v1 weight: 900 → 700 → 500 → 100 → 0Multi-Tenant SaaS
Isolate tenants with custom policies:
# Tenant routing
routes:
- name: tenant-a
hosts:
- tenant-a.api.example.com
service: tenant-a-service
- name: tenant-b
hosts:
- tenant-b.api.example.com
service: tenant-b-service
# Per-tenant rate limiting
consumers:
- username: tenant-a
custom_id: tenant-a-001
plugins:
- name: rate-limiting
consumer: tenant-a
config:
minute: 1000 # Premium tier
consumers:
- username: tenant-b
custom_id: tenant-b-002
plugins:
- name: rate-limiting
consumer: tenant-b
config:
minute: 100 # Free tier
# Add tenant context to requests
plugins:
- name: request-transformer
config:
add:
headers:
- "X-Tenant-ID:$(consumer_custom_id)"Mobile Backend Gateway
Optimized for mobile apps:
services:
- name: mobile-api
url: http://mobile-backend:8001
routes:
- name: mobile-v1
service: mobile-api
paths:
- /mobile/v1
strip_path: true
plugins:
# Aggressive caching for mobile
- name: proxy-cache
route: mobile-v1
config:
strategy: redis
cache_ttl: 3600
vary_headers:
- X-App-Version
# Device-based rate limiting
- name: rate-limiting
route: mobile-v1
config:
limit_by: header
header_name: X-Device-ID
minute: 100
# Response compression
- name: response-transformer
route: mobile-v1
config:
add:
headers:
- "Content-Encoding:gzip"
# Request size limiting (protect uploads)
- name: request-size-limiting
route: mobile-upload
config:
allowed_payload_size: 10 # MBDistributed Tracing
Track requests across microservices:
plugins:
# Zipkin tracing
- name: zipkin
config:
http_endpoint: http://zipkin:9411/api/v2/spans
sample_ratio: 0.1 # Trace 10%
include_credential: true
# Or OpenTelemetry
- name: opentelemetry
config:
endpoint: http://jaeger:14268/api/traces
resource_attributes:
service.name: api-gateway
service.version: 1.0.0
batch_span_processor:
max_queue_size: 2048
# Propagate trace context
- name: request-transformer
config:
add:
headers:
- "X-Request-ID:$(uuid)"
- "X-Trace-ID:$(traceid)"Best Practices
Configuration Management
1. Use Declarative Config: Version control YAML files with Git 2. Environment Separation: Separate configs for dev/staging/prod 3. Validate Before Deploy: Test configs in staging first 4. Atomic Updates: Use decK for all-or-nothing deployments 5. Backup Configs: Regular backups of working configurations
Security
1. Always Use HTTPS: Encrypt client-gateway and gateway-upstream 2. Implement Authentication: Never expose public APIs without auth 3. Rate Limit Everything: Protect against abuse and DDoS 4. Validate Input: Use request-validator plugin 5. Rotate Secrets: Regularly rotate API keys and certificates 6. Least Privilege: Minimal permissions for consumers 7. Monitor Access: Log and alert on suspicious activity
Performance
1. Enable Caching: Cache responses aggressively 2. Use Connection Pooling: Reuse upstream connections 3. Set Appropriate Timeouts: Prevent resource exhaustion 4. Optimize Plugins: Only enable necessary plugins 5. Monitor Latency: Track request/response times 6. Scale Horizontally: Add Kong nodes for traffic growth
Reliability
1. Health Checks: Monitor upstream service health 2. Circuit Breakers: Fail fast when dependencies down 3. Retry Logic: Handle transient failures automatically 4. Load Balancing: Distribute load across instances 5. Graceful Degradation: Serve cached or default responses 6. Disaster Recovery: Plan for Kong node failures
Observability
1. Structured Logging: Use JSON logs for parsing 2. Distributed Tracing: Trace requests across services 3. Metrics Collection: Export Prometheus metrics 4. Alerting: Set up alerts for errors and latency 5. Dashboards: Visualize gateway performance 6. Health Endpoints: Expose /health and /metrics
Troubleshooting
Common Issues
Gateway returns 502/503:
- Check upstream service health
- Verify network connectivity to upstream
- Review timeout settings
- Check upstream health check config
Authentication failing:
- Verify consumer credentials are correct
- Check plugin configuration (key names, claims)
- Review request headers (Authorization, apikey)
- Ensure plugin is enabled on correct scope
Rate limiting not working:
- Verify policy setting (local vs cluster vs redis)
- Check Redis connectivity if using redis policy
- Review limit_by configuration
- Ensure consumer identification is working
High latency:
- Check upstream response times
- Review plugin overhead (disable plugins to isolate)
- Verify connection pooling settings
- Check DNS resolution times
- Review database performance (if using DB mode)
Cache not working:
- Verify cache strategy (memory vs redis)
- Check cache_control setting
- Review vary_headers configuration
- Ensure content_type is cacheable
- Check Redis connectivity (if using redis)
Debugging Techniques
Enable Debug Logging:
# Set log level to debug
export KONG_LOG_LEVEL=debug
kong restartCheck Admin API:
# Verify service configuration
curl http://localhost:8001/services/my-service
# Check route configuration
curl http://localhost:8001/routes/my-route
# List enabled plugins
curl http://localhost:8001/pluginsTest Upstream Directly:
# Bypass gateway to test upstream
curl http://upstream-host:8001/endpointReview Logs:
# Proxy logs
tail -f /usr/local/kong/logs/access.log
# Error logs
tail -f /usr/local/kong/logs/error.logTools & Resources
Essential Tools
- decK: Declarative configuration management - https://docs.konghq.com/deck/
- Insomnia: API client with Kong integration - https://insomnia.rest/
- Kong Manager: GUI for Kong management (Enterprise) - https://docs.konghq.com/gateway/latest/kong-manager/
- Konga: Open-source Kong admin UI - https://pantsel.github.io/konga/
Monitoring & Observability
- Prometheus: Metrics collection - https://prometheus.io/
- Grafana: Metrics visualization - https://grafana.com/
- Zipkin: Distributed tracing - https://zipkin.io/
- Jaeger: Distributed tracing - https://www.jaegertracing.io/
- ELK Stack: Logging (Elasticsearch, Logstash, Kibana) - https://www.elastic.co/
Development Tools
- Postman: API testing - https://www.postman.com/
- HTTPie: CLI HTTP client - https://httpie.io/
- curl: Universal HTTP client
- jq: JSON processor for API responses - https://stedolan.github.io/jq/
Learning Resources
- Kong Docs: https://docs.konghq.com/
- Kong Plugin Hub: https://docs.konghq.com/hub/
- Kong University: https://education.konghq.com/
- Kong Blog: https://konghq.com/blog/
- Kong Community: https://discuss.konghq.com/
Architecture Patterns
Single Gateway (Simple)
Clients → Kong Gateway → Backend ServicesMulti-Region (Global)
Clients → DNS/GeoDNS → Regional Kong Clusters → Regional ServicesHybrid (Enterprise)
Control Plane (Config Management)
↓
Data Plane Nodes (Traffic Handling)
↓
Backend ServicesService Mesh Integration
Clients → Kong (North-South) → Istio/Linkerd (East-West) → ServicesPerformance Benchmarks
Typical Performance (single Kong node)
- Throughput: 10,000-50,000 req/s (depends on plugins)
- Latency: 1-5ms added latency (minimal plugins)
- CPU Usage: 2-4 cores for 10,000 req/s
- Memory: 512MB-2GB (depends on cache size)
Scaling Guidelines
- 0-1K req/s: Single Kong node sufficient
- 1K-10K req/s: 2-3 Kong nodes with load balancing
- 10K-50K req/s: 5-10 Kong nodes, consider caching
- 50K+ req/s: Horizontal scaling, CDN integration, regional deployment
Next Steps
1. Read SKILL.md: Comprehensive patterns and examples 2. Review EXAMPLES.md: Detailed implementation examples 3. Set Up Local Environment: Install Kong locally 4. Experiment with Plugins: Try different plugin combinations 5. Build Production Config: Design gateway for your use case 6. Monitor and Optimize: Set up observability and tune performance
---
Version: 1.0.0 Last Updated: October 2025 Maintainer: API Gateway Patterns Team
Related skills
FAQ
What does api-gateway-patterns cover?
api-gateway-patterns addresses routing, authentication, rate limiting, response aggregation, and service-mesh boundaries when multiple microservices share one public API edge instead of exposing each service directly.
When should developers use api-gateway-patterns?
api-gateway-patterns fits backend builds where several services need centralized TLS termination, token validation, quotas, and consistent routing rather than repeating auth and throttle middleware in every repository.