Loading...
Loading...
Comprehensive API gateway patterns skill covering Kong, routing, rate limiting, authentication, load balancing, traffic management, and production gateway architecture
npx skill4agent add manutej/luxor-claude-marketplace api-gateway-patternsService (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)# 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: truestrip_path: truestrip_path: falsepreserve_host: true# 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 default# 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-api# 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
- DELETE# 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-api# 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:
- /apiplugins:
- 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'localclusterredis# 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 enterprise# 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 pluginplugins:
- 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: 0plugins:
- 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: 1000000# 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_abc123def456ghi789curl -H "apikey: sk_live_abc123def456ghi789" \
https://api.example.com/usersplugins:
- 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-productionjwt_secrets:
- consumer: mobile-app
key: mobile-issuer
algorithm: RS256
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJteWFwcC1pc3N1ZXIiLCJzdWIiOiJ1c2VyMTIzIiwiZXhwIjoxNjQwOTk1MjAwfQ.signatureplugins:
- 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/callback# 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/callbackplugins:
- 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-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-secret# 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=MyOrgupstreams:
- 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: 100upstreams:
- 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: 200upstreams:
- 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:8001hash_on: nonehash_on: consumerhash_on: iphash_on: headerhash_on: cookiehash_on: pathhash_on: headerhash_on: iphash_on: headerhash_on: cookieupstreams:
- name: websocket-upstream
algorithm: least-connections
targets:
- target: ws-1.internal:8001
- target: ws-2.internal:8001
- target: ws-3.internal:8001upstreams:
- 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: 2plugins:
- 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 successesservices:
- 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: 30000connect_timeout: 2s → Connection establishment
write_timeout: 5s → Writing request to upstream
read_timeout: 5s → Reading response from upstream
http_timeout: 5s → Overall HTTP transactionservices:
- 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.5Attempt 1: Immediate
Attempt 2: 2s + jitter
Attempt 3: 4s + jitter
Attempt 4: 8s + jitter
Attempt 5: 16s + jitterplugins:
- 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 APIsplugins:
- 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 connectionsplugins:
- 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"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"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'"plugins:
- name: request-transformer-advanced
config:
add:
body:
- "gateway_timestamp:$(timestamp)"
- "request_id:$(uuid)"
remove:
body:
- "internal_field"
replace:
body:
- "api_version:v2"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/users# 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
- httpsplugins:
- 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"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:26379plugins:
- 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: true# 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 cachesClient
↓
Kong Gateway Cache (L1)
↓
Backend API Cache (L2)
↓
Database# 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"# 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-123plugins:
- 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: falseplugins:
- name: cors
config:
origins:
- "*"
methods:
- "*"
headers:
- "*"
credentials: false # Must be false with wildcard origins# 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/24# Admin route: IP + Auth
plugins:
- name: ip-restriction
route: admin-api
config:
allow:
- 10.0.0.0/8
- name: key-auth
route: admin-apiplugins:
- name: bot-detection
config:
allow:
- "googlebot"
- "bingbot"
- "slackbot"
deny:
- "curl"
- "wget"
- "scrapy"
blacklist_cache_size: 10000
whitelist_cache_size: 10000plugins:
- 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: 1plugins:
- name: waf # Kong Enterprise or ModSecurity plugin
config:
rule_sets:
- owasp_crs
anomaly_threshold: 5
paranoia_level: 1
blocked_status_code: 403plugins:
- 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')"# 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: 8125# 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: 5000plugins:
- name: opentelemetry
config:
propagation:
default: w3c
headers:
- traceparent
- tracestateplugins:
- 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-service# 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}# 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: 3# 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"
endconfig/
├── base.yaml # Shared configuration
├── dev.yaml # Development overrides
├── staging.yaml # Staging overrides
└── production.yaml # Production overrides# 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: 1000# 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-blue# 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: 10Phase 1: 5% canary, monitor errors
Phase 2: 25% canary, check metrics
Phase 3: 50% canary, verify performance
Phase 4: 100% canary, deprecate old version# 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"# 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-service1. 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)# 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)"# 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:
- exp# 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: 100# 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:5000# 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% new# 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/pluginsservices:
- name: my-service
url: http://api.internal:8001
routes:
- name: my-route
service: my-service
paths:
- /apiservices:
- 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-route