Back to catalog

api-gateway-patterns

Comprehensive API gateway patterns skill covering Kong, routing, rate limiting, authentication, load balancing, traffic management, and production gateway architecture

  • Category: discovered
  • Tags: github, community
  • Version: 1.0.0
  • Author: walid
  • Downloads: 0
  • Updated: 2025-11-22

Download the latest version (v1.0.0) from this page.

SKILL.md

---
name: api-gateway-patterns
description: Comprehensive API gateway patterns skill covering Kong, routing, rate limiting, authentication, load balancing, traffic management, and production gateway architecture
---

# 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:**
```yaml
# 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: true
```

**Key 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:**
```yaml
# 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
```

**Advanced Header Routing:**
```yaml
# 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
```

### Pattern 3: Method-Based Routing

Route different HTTP methods to specialized services.

**Use Case:** CQRS pattern - separate read and write services

**Configuration:**
```yaml
# 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
```

### Pattern 4: Host-Based Routing

Route based on the requested hostname for multi-tenant applications.

**Use Case:** Different subdomains for different customers or environments

**Configuration:**
```yaml
# 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
```

### Pattern 5: Weighted Routing (Canary Deployments)

Gradually shift traffic between service versions.

**Implementation:**
```yaml
# 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:
      - /api
```

**Gradual 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:**
```yaml
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 database
- `redis`: 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:**
```yaml
# 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
```

### Pattern 3: Endpoint-Specific Rate Limiting

Different limits for different API endpoints.

**Use Case:** Protect expensive operations while allowing higher rates for cheap ones

**Configuration:**
```yaml
# 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 plugin
```

### Pattern 4: Sliding Window Rate Limiting

More accurate rate limiting using sliding windows.

**Use Case:** Prevent burst attacks that exploit fixed window boundaries

**Configuration:**
```yaml
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: 0
```

**Sliding 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:**
```yaml
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: 1000000
```

## Authentication Patterns

### Pattern 1: API Key Authentication

Simple API key validation for basic security.

**Use Case:** Internal APIs, development environments, simple integrations

**Configuration:**
```yaml
# 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_abc123def456ghi789
```

**Usage:**
```bash
curl -H "apikey: sk_live_abc123def456ghi789" \
  https://api.example.com/users
```

**Best 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:**
```yaml
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-production
```

**RS256 (Asymmetric) Configuration:**
```yaml
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.signature
```

### Pattern 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:**
```yaml
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/callback
```

**Authorization Code Flow:**
```bash
# 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/callback
```

### Pattern 4: OpenID Connect (OIDC)

Enterprise SSO integration with identity providers.

**Use Case:** Enterprise authentication with Google, Okta, Auth0, Azure AD

**Configuration:**
```yaml
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-configuration
```

**Multi-Provider Configuration:**
```yaml
# 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
```

### Pattern 5: mTLS (Mutual TLS) Authentication

Certificate-based authentication for service-to-service security.

**Use Case:** Microservices mutual authentication, B2B integrations

**Configuration:**
```yaml
# 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=MyOrg
```

## Load Balancing Patterns

### Pattern 1: Round-Robin Load Balancing

Distribute requests evenly across service instances.

**Use Case:** Stateless services with uniform capacity

**Configuration:**
```yaml
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: 100
```

### Pattern 2: Weighted Load Balancing

Distribute traffic proportionally based on server capacity.

**Use Case:** Heterogeneous servers with different capacities

**Configuration:**
```yaml
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: 200
```

**Weight 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:**
```yaml
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:8001
```

**Hashing Options:**
- `hash_on: none` - Random distribution
- `hash_on: consumer` - Hash by authenticated consumer
- `hash_on: ip` - Hash by client IP
- `hash_on: header` - Hash by specified header value
- `hash_on: cookie` - Hash by cookie value
- `hash_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:**
```yaml
upstreams:
  - name: websocket-upstream
    algorithm: least-connections

targets:
  - target: ws-1.internal:8001
  - target: ws-2.internal:8001
  - target: ws-3.internal:8001
```

**When 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:**
```yaml
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
          successe