Kong Gateway Samples

Kong API Gateway configuration examples including services, routes, plugins, authentication, load balancing, and monitoring setup

Key Facts

Category
API Gateway
Items
2
Format Families
sample

Sample Overview

Kong API Gateway configuration examples including services, routes, plugins, authentication, load balancing, and monitoring setup This sample set belongs to API Gateway and can be used to test related workflows inside Elysia Tools.

⚙️ Kong Gateway Basic Setup

🟡 intermediate ⭐⭐⭐

Essential Kong Gateway configuration including services, routes, plugins, and basic API management

⏱️ 35 min 🏷️ kong, api-gateway, infrastructure, microservices
Prerequisites: Docker, PostgreSQL, API concepts, Microservices architecture
# Kong Gateway Basic Configuration
# Complete setup for API Gateway with services, routes, and plugins

# 1. Docker Compose Setup
# docker-compose.yml
version: '3.8'

services:
  kong-database:
    image: postgres:13
    restart: always
    environment:
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kongpass
      POSTGRES_DB: kong
    ports:
      - "5432:5432"
    volumes:
      - kong_data:/var/lib/postgresql/data
    networks:
      - kong-net

  kong-migration:
    image: kong/kong-gateway:3.4
    command: kong migrations bootstrap
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpass
      KONG_PG_DATABASE: kong
    depends_on:
      - kong-database
    networks:
      - kong-net

  kong:
    image: kong/kong-gateway:3.4
    restart: on-failure
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpass
      KONG_PG_DATABASE: kong
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
      KONG_PROXY_LISTEN: 0.0.0.0:8000
    ports:
      - "8000:8000"  # Proxy port
      - "8001:8001"  # Admin API port
    depends_on:
      - kong-migration
    networks:
      - kong-net

  konga:
    image: pantsel/konga:next
    environment:
      NODE_ENV: development
    ports:
      - "1337:1337"
    depends_on:
      - kong
    networks:
      - kong-net

volumes:
  kong_data:

networks:
  kong-net:
    driver: bridge

# 2. Service Configuration - User Service
# Create a service pointing to user microservice
curl -X POST http://localhost:8001/services \
  --data 'name=user-service \
  &url=http://user-service:3001'

# Add route to user service
curl -X POST http://localhost:8001/services/user-service/routes \
  --data 'name=user-api \
  &paths[]=/api/users \
  &methods[]=GET,POST,PUT,DELETE'

# 3. Service Configuration - Product Service with health check
curl -X POST http://localhost:8001/services \
  --data 'name=product-service \
  &url=http://product-service:3002 \
  &connect_timeout=10000 \
  &write_timeout=10000 \
  &read_timeout=10000 \
  &retries=3 \
  &protocol=http'

# Add multiple routes to product service
curl -X POST http://localhost:8001/services/product-service/routes \
  --data 'name=products-api \
  &paths[]=/api/products \
  &methods[]=GET,POST'

curl -X POST http://localhost:8001/services/product-service/routes \
  --data 'name=product-search-api \
  &paths[]=/api/products/search \
  &methods[]=GET

curl -X POST http://localhost:8001/services/product-service/routes \
  --data 'name=product-categories-api \
  &paths[]=/api/products/categories \
  &methods[]=GET'

# 4. Load Balancer Configuration
# Create service with upstream for load balancing
curl -X POST http://localhost:8001/upstreams \
  --data 'name=user-service-upstream \
  &algorithm=round-robin \
  &healthchecks.path=/health \
  &healthchecks.healthy.interval=10 \
  &healthchecks.healthy.http_statuses=200,201 \
  &healthchecks.unhealthy.interval=5 \
  &healthchecks.unhealthy.http_statuses=404,500,502,503 \
  &healthchecks.unhealthy.timeout=5'

# Add targets to upstream (multiple instances)
curl -X POST http://localhost:8001/upstreams/user-service-upstream/targets \
  --data 'target=user-service-1:3001 \
  &weight=100'

curl -X POST http://localhost:8001/upstreams/user-service-upstream/targets \
  --data 'target=user-service-2:3001 \
  &weight=100'

curl -X POST http://localhost:8001/upstreams/user-service-upstream/targets \
  --data 'target=user-service-3:3001 \
  &weight=50 \
  &tags[]=canary'

# Create service pointing to upstream
curl -X POST http://localhost:8001/services \
  --data 'name=user-service-balanced \
  &url=http://user-service-upstream'

# 5. Plugin Configuration - Rate Limiting
# Global rate limiting
curl -X POST http://localhost:8001/plugins \
  --data 'name=rate-limiting \
  &config.minute=100 \
  &config.hour=5000 \
  &config.policy=local'

# Service-specific rate limiting
curl -X POST http://localhost:8001/services/user-service/plugins \
  --data 'name=rate-limiting \
  &config.minute=50 \
  &config.hour=2000 \
  &config.policy=cluster

# Advanced rate limiting with different limits
curl -X POST http://localhost:8001/services/product-service/plugins \
  --data 'name=rate-limiting-advanced \
  &config.limits.minute=100 \
  &config.limits.hour=5000 \
  &config.limits.day=50000 \
  &config.block_duration=60 \
  &config.policy=cluster'

# 6. Authentication and Authorization
# JWT Plugin Configuration
curl -X POST http://localhost:8001/plugins \
  --data 'name=jwt \
  &config.secret_is_base64=false \
  &config.key=secret-key \
  &config.algorithm=HS256 \
  &config.claims_to_verify=exp,iat,nbf \
  &config.header_names=authorization:x-authorization'

# CORS Plugin Configuration
curl -X POST http://localhost:8001/plugins \
  --data 'name=cors \
  &config.origins=* \
  &config.methods=GET,POST,PUT,DELETE,OPTIONS \
  &config.headers=Accept,Accept-Version,Content-Length,Content-MD5,Content-Type,Date,X-Auth-Token \
  &config.exposed_headers=X-Total-Count,X-Pagination-Count,X-Pagination-Limit \
  &config.credentials=true \
  &config.max_age=3600'

# OAuth2 Plugin Configuration
curl -X POST http://localhost:8001/plugins \
  --data 'name=oauth2 \
  &config.scopes=email,profile \
  &config.mandatory_scope=email \
  &config.provision_key=provision-key \
  &config.enable_authorization_code=true \
  &config.enable_client_credentials=true \
  &config.enable_password_grant=true'

# ACL Plugin for Role-Based Access Control
curl -X POST http://localhost:8001/plugins \
  --data 'name=acl \
  &config.hide_groups_header=true \
  &config.whitelist=admin,user,premium'

# 7. Request/Response Transformation
# Request Transformer Plugin
curl -X POST http://localhost:8001/services/user-service/plugins \
  --data 'name=request-transformer \
  &config.add.headers[X-Custom-Header]=custom-value \
  &config.add.headers[X-Request-ID]=uuid \
  &config.remove.headers=authorization \
  &config.replace.headers=Content-Type=application/json'

# Response Transformer Plugin
curl -X POST http://localhost:8001/services/user-service/plugins \
  --data 'name=response-transformer \
  &config.add.headers=X-Service=user-service \
  &config.add.headers=X-Cache-Hit=MISS \
  &config.remove.headers=X-Powered-By \
  &config.replace.headers=Content-Type=application/vnd.api+json'

# Request Size Limiting
curl -X POST http://localhost:8001/plugins \
  --data 'name=request-size-limiting \
  &config.allowed_payload_size=10 \
  &config.size_unit=mb'

# 8. Security Plugins
# IP Restriction Plugin
curl -X POST http://localhost:8001/services/admin-api/plugins \
  --data 'name=ip-restriction \
  &config.whitelist=192.168.1.0/24,10.0.0.0/8 \
  &config.blacklist=10.0.0.100

# Basic Authentication
curl -X POST http://localhost:8001/services/legacy-api/plugins \
  --data 'name=basic-auth \
  & config.hide_credentials=true'

# API Key Authentication
curl -X POST http://localhost:8001/services/external-api/plugins \
  --data 'name=key-auth \
  &config.hide_credentials=false'

# Add API Key
curl -X POST http://localhost:8001/consumers \
  --data 'username=api-consumer'

curl -X POST http://localhost:8001/consumers/api-consumer/key-auth \
  --data 'key=super-secret-api-key'

# 9. Monitoring and Analytics
# Prometheus Metrics Plugin
curl -X POST http://localhost:8001/plugins \
  --data 'name=prometheus \
  &config.per_consumer=true \
  &config.per_service=true \
  &config.per_route=true \
  &config.latency_metrics=true \
  &config.bandwidth_metrics=true'

# DataDog Plugin
curl -X POST http://localhost:8001/plugins \
  --data 'name=datadog \
  &config.host=datadog-agent \
  &config.port=8125 \
  &config.metrics=true \
  &config.host=statsd-exporter'

# Request Logging Plugin
curl -X POST http://localhost:8001/plugins \
  --data 'name=request-termination \
  &config.log_body=true \
  &config.body_bytes=4096'

# 10. Custom Plugin Development
# Custom Plugin Structure (my-plugin/kong/plugins/my-plugin/handler.lua)
local BasePlugin = require "kong.plugins.base_plugin"

local MyPlugin = BasePlugin:extend()

MyPlugin.PRIORITY = 1000
MyPlugin.VERSION = "1.0.0"

function MyPlugin:new()
  MyPlugin.super.new(self, "my-plugin")
  return self
end

function MyPlugin:access(conf)
  -- Add custom headers
  kong.response.add_header("X-Custom-Plugin", "active")

  -- Log request
  kong.log.info("Custom plugin executed")

  -- Custom logic based on request
  local path = kong.request.get_path()
  if string.match(path, "/admin") then
    -- Check custom header for admin access
    local admin_header = kong.request.get_header("X-Admin-Token")
    if not admin_header or admin_header ~= "secret-admin-token" then
      return kong.response.exit(403, "Admin access required")
    end
  end
end

function MyPlugin:body_filter(conf)
  -- Modify response body
  local body = kong.service.response.get_raw_body()
  if body then
    -- Add timestamp to JSON responses
    kong.service.response.set_raw_body(body:gsub("}", ',"timestamp":"' .. os.date() .. '"}'))
  end
end

return MyPlugin

# 11. Service Mesh Integration
# Kubernetes Service Discovery
curl -X POST http://localhost:8001/upstreams \
  --data 'name=k8s-services \
  &algorithm=round-robin \
  &healthchecks.path=/health \
  &healthchecks.healthy.interval=10'

# Add Kubernetes services as targets
curl -X POST http://localhost:8001/upstreams/k8s-services/targets \
  --data 'target=user-service.default.svc.cluster.local:80'

# Consul Service Discovery Plugin
curl -X POST http://localhost:8001/plugins \
  --data 'name=consul \
  &config.host=consul.default.svc.cluster.local \
  &config.port=8500 \
  &config.register=false \
  &config.query_timeout=2000 \
  &config.keepalive=30000 \
  &config.default_target=80'

# 12. Environment-Specific Configurations
# Development Environment (dev-kong.conf)
database = postgres
pg_host = kong-database
pg_user = kong
pg_password = kongpass
pg_database = kong

proxy_access_log = /dev/stdout
admin_access_log = /dev/stdout
log_level = debug

# Development specific plugins
plugins = bundled,cors,request-size-limiting

# Production Environment (prod-kong.conf)
database = postgres
pg_host = prod-kong-db.internal
pg_user = kong
pg_password = ${KONG_PG_PASSWORD}
pg_database = kong

proxy_access_log = /var/log/kong/access.log
admin_access_log = /var/log/kong/admin.log
log_level = warn

# Production plugins with security
plugins = bundled,cors,jwt,acl,ip-restriction,prometheus,rate-limiting

# 13. Kong Declarative Configuration
# kong.yml (declarative configuration format)
_format_version: "1.1"
services:
  - name: user-service
    url: http://user-service:3001
    plugins:
      - name: rate-limiting
        config:
          minute: 100
          hour: 5000
    routes:
      - name: user-api
        paths: ["/api/users"]
        methods: [GET,POST,PUT,DELETE]

  - name: product-service
    url: http://product-service:3002
    plugins:
      - name: jwt
        config:
          secret_is_base64: false
          key: secret-key
    routes:
      - name: products-api
        paths: ["/api/products"]
        methods: [GET,POST]

plugins:
  - name: cors
    config:
      origins: ["*"]
      methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
      headers: ["Accept", "Content-Type", "Authorization"]

  - name: prometheus
    config:
      per_consumer: true
      per_service: true

# 14. Admin API Automation Script
# setup-kong.sh
#!/bin/bash

# Wait for Kong to start
until curl -s http://localhost:8001 > /dev/null; do
  echo "Waiting for Kong to start..."
  sleep 2
done

echo "Kong is ready. Setting up services..."

# Create services
for service in user-service:3001 product-service:3002 order-service:3003; do
  name=${service%:*}
  url=http://${service#*:}

  echo "Creating service: $name -> $url"
  curl -s -X POST http://localhost:8001/services \
    --data "name=$name&url=$url" > /dev/null
done

# Create routes
declare -A routes=(
  ["user-service"="/api/users"]
  ["product-service"="/api/products"]
  ["order-service"="/api/orders"]
)

for service in "${!routes[@]}"; do
  name=${routes[$service]}

  echo "Creating route: $name -> $service"
  curl -s -X POST http://localhost:8001/services/$service/routes \
    --data "name=$name-Route&paths[]=$name&methods[]=GET,POST" > /dev/null
done

# Add rate limiting
curl -X POST http://localhost:8001/plugins \
  --data 'name=rate-limiting&config.minute=100&config.hour=5000'

echo "Kong setup completed!"

# 15. Health Check and Monitoring
# health-check.sh
#!/bin/bash

KONG_ADMIN_URL="http://localhost:8001"
KONG_PROXY_URL="http://localhost:8000"

echo "Checking Kong health..."

# Check admin API
if curl -s "$KONG_ADMIN_URL" > /dev/null; then
  echo "✓ Admin API is healthy"
else
  echo "✗ Admin API is not responding"
  exit 1
fi

# Check proxy
if curl -s "$KONG_PROXY_URL" > /dev/null; then
  echo "✓ Proxy is healthy"
else
  echo "✗ Proxy is not responding"
  exit 1
fi

# Check database connection
if curl -s "$KONG_ADMIN_URL/services" > /dev/null; then
  echo "✓ Database connection is working"
else
  echo "✗ Database connection failed"
  exit 1
fi

echo "All Kong health checks passed!"

# Load test configuration
# load-test.js (using Artillery or similar)
{
  "config": {
    "target": "http://localhost:8000",
    "phases": [
      {
        "duration": 60,
        "arrivalRate": 100
      },
      {
        "duration": 120,
        "arrivalRate": 200
      },
      {
        "duration": 60,
        "arrivalRate": 500
      }
    ]
  },
  "scenarios": [
    {
      "name": "User Service Load Test",
      "weight": 50,
      "flow": [
        {
          "get": {
            "url": "/api/users"
          }
        }
      ]
    },
    {
      "name": "Product Service Load Test",
      "weight": 30,
      "flow": [
        {
          "get": {
            "url": "/api/products"
          }
        }
      ]
    },
    {
      "name": "Health Check",
      "weight": 20,
      "flow": [
        {
          "get": {
            "url": "/health"
          }
        }
      ]
    }
  ]
}

⚙️ Kong Gateway Advanced Features

🔴 complex ⭐⭐⭐⭐

Advanced Kong Gateway features including custom plugins, service mesh integration, monitoring, and enterprise security

⏱️ 60 min 🏷️ kong, api-gateway, advanced, enterprise
Prerequisites: Kong basics, Docker, PostgreSQL, Enterprise security, Monitoring
# Kong Gateway Advanced Configuration
# Enterprise-grade features and patterns

# 1. Multi-Region Setup with Active-Active
# Primary Region Configuration
# kong-primary.yml
_format_version: "1.1"

# Service pointing to multi-region upstream
services:
  - name: payment-service
    url: http://payment-balancer
    retries: 3
    connect_timeout: 10000
    write_timeout: 10000
    read_timeout: 10000
    plugins:
      - name: rate-limiting
        config:
          minute: 1000
          hour: 50000
          fault_tolerant: true
      - name: circuit-breaker
        config:
          thresholds:
            memory_usage: 80
            latency: {maximum_ms: 1000, sample_size: 100}
          healthy:
            success_rate: 0.95
    routes:
      - name: payment-api
        paths: ["/api/payments"]
        methods: [POST, GET, PUT]
        plugins:
          - name: request-id
          - name: prometheus
            config:
              per_service: true
              per_route: true
              latency_metrics: true

# Multi-region upstream configuration
upstreams:
  - name: payment-balancer
    algorithm: round-robin
    healthchecks:
      active:
        http_path: /health
        healthy:
          interval: 5
          successes: 3
        unhealthy:
          interval: 5
          http_failures: 3
      passive:
        type: http
        healthy:
          http_statuses: [200, 201, 202, 204]
          success_rate: 0.95
    targets:
      - target: payment-primary.region1.company.com:80
        weight: 1
        tags: [primary, region1]
      - target: payment-secondary.region1.company.com:80
        weight: 1
        tags: [secondary, region1]
      - target: payment-primary.region2.company.com:80
        weight: 1
        tags: [primary, region2]

# 2. Advanced Authentication and Authorization
# OAuth 2.0 with JWT and RBAC
# Create OAuth2 plugin for secure access
curl -X POST http://localhost:8001/plugins \
  --data 'name=oauth2 \
  &config.scopes=read,write,admin \
  &config.mandatory_scope=read \
  &config.provision_key=your-provision-key \
  &config.global_credentials=true \
  &config.enable_authorization_code=true \
  &config.enable_client_credentials=true \
  &config.enable_password_grant=true \
  &config.refresh_token_ttl=7200 \
  &config.access_token_ttl=3600 \
  &config.auth_methods=basic-auth'

# JWT Plugin with custom claims validation
curl -X POST http://localhost:8001/plugins \
  --data 'name=jwt \
  &config.secret_is_base64=false \
  &config.algorithm=RS256 \
  &config.key=your-rsa-public-key \
  &config.private_key=your-rsa-private-key \
  &config.claims_to_verify=exp,iat,nbf,jti \
  &config.claims_to_include=user_id,roles,permissions \
  &config.jwt_header_name=Authorization \
  &config.expired_jwt_claim=exp \
  &config.run_on_preflight=true'

# ACL Plugin for Role-Based Access Control
curl -X POST http://localhost:8001/plugins \
  --data 'name=acl \
  &config.whitelist=admin,user,premium,support \
  &config.hide_groups_header=false \
  &config.log_errors=true'

# Request Transformer for adding user context
curl -X POST http://localhost:8001/plugins \
  --data 'name=request-transformer \
  &config.add.headers=X-Auth-Time=${jwt.claims.iat} \
  &config.add.headers=X-User-Id=${jwt.claims.user_id} \
  &config.add.headers=X-User-Role=${jwt.claims.roles}'

# 3. Advanced Monitoring and Observability
# Comprehensive monitoring setup

# OpenTelemetry Plugin
curl -X POST http://localhost:8001/plugins \
  --data 'name=opentelemetry \
  &config.resource_attributes=service.name=payment-service,service.version=1.0.0 \
  &config.sampler=always_on \
  &config.collect_metrics=false \
  &config.collect_traces=true \
  &config.api_key=your-otel-api-key \
  &config.endpoint=http://otel-collector:4318/v1/traces \
  &config.headers=X-API-Key=your-api-key \
  &config.timeout=10000 \
  &config.batch_count=512 \
  &config.batch_size=1024 \
  &config.compression=gzip'

# DataDog APM Integration
curl -X POST http://localhost:8001/plugins \
  --data 'name=datadog \
  &config.host=datadog-agent.default.svc.cluster.local \
  &config.port=8125 \
  &config.metrics=true \
  &config.tags=environment:production,service:kong-gateway \
  &config.service_name=kong-gateway \
  &config.hostname=kong-gateway-1 \
  &config.constants=service.name:kong,service.version:3.4.0 \
  &config.spans=forbidden_list,external_requests,deadlock,host_latency,jemalloc,ngx_worker_mutex_metrics,os_scheduler_metrics,os_threading_metrics,postgres_query_timing,rpm_os_metrics,rpm_vm_metrics,upload_time_metrics,upload_time_successful,upload_time_failed

# Custom Logging Plugin for Business Metrics
curl -X POST http://localhost:8001/plugins \
  --data 'name=file-log \
  &config.path=/var/log/kong/business-metrics.log \
  &config.reopen=true \
  &config.log_body=false \
  &config.message_template=${time_stamp}[${request.method}] ${request.host}${request.path}: response_time=${response.time}ms, status=${response.status}, user=${headers.X-User-Id}, role=${headers.X-User-Role}

# 4. Dynamic Configuration with Declarative Config
# Enable declarative config
curl -X PATCH http://localhost:8001/config \
  --data '{"declarative_config": true}'

# Create directory for declarative configs
mkdir -p /etc/kong/declarative

# Environment-specific declarative configs
# /etc/kong/declarative/kong.yml
_format_version: "1.1"

# Common plugins (loaded everywhere)
plugins:
  - name: prometheus
    config:
      per_consumer: true
      per_service: true
      per_route: true
      latency_metrics: true
  - name: request-id
    config: header_name: X-Request-ID
  - name: cors
    config:
      origins: ["*"]
      methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
      headers: ["Accept", "Content-Type", "Authorization"]
      exposed_headers: ["X-Total-Count", "X-Pagination-Count"]
      credentials: true
  - name: rate-limiting
    config:
      minute: 1000
      hour: 50000
      fault_tolerant: true
      skip_on_http_codes: [404, 500, 502, 503]

# Service definitions
services:
  - name: user-service
    url: http://user-service:3001
    plugins:
      - name: acl
        config:
          whitelist: [user, admin]
          hide_groups_header: true
      - name: jwt
        config:
          key: user-service-jwt-secret
          secret_is_base64: false
    routes:
      - name: user-api
        paths: ["/api/users"]
        methods: [GET, POST, PUT, DELETE]
        plugins:
          - name: request-transformer
            config:
              add:
                headers:
                  X-Service: user-service
                  X-Version: v1

# 5. Circuit Breaker and Fault Tolerance
# Circuit Breaker Plugin Configuration
curl -X POST http://localhost:8001/services/critical-service/plugins \
  --data 'name=circuit-breaker \
  &config.provisioning=0 \
  &config.timeout=30 \
  &config.thresholds.latency.maximum_ms=1000 \
  &config.thresholds.latency.sample_size=100 \
  &config.thresholds.memory_usage=80 \
  &config.thresholds.network_errors=10 \
  &config.success_rate.percentage=95 \
  &config.failure_rate.percentage=5 \
  &config.ttl=600 \
  &config.allow_discovery=true \
  &config.load_balancing_policy=least_connections \
  &config.fallback.name=custom-fallback \
  &config.fallback.code=404,500,503,504 \
  &config.fallback.show_error=true

# Custom Fallback Plugin for Circuit Breaker
# custom-fallback/handler.lua
local BasePlugin = require "kong.plugins.base_plugin"

local CustomFallback = BasePlugin:extend()

CustomFallback.PRIORITY = 1000
CustomFallback.VERSION = "1.0.0"

function CustomFallback:new()
  CustomFallback.super.new(self, "custom-fallback")
  return self
end

function CustomFallback:body_filter(conf)
  if kong.response.get_status() >= 500 then
    local fallback_response = {
      error = "Service temporarily unavailable",
      message = "The service is currently experiencing issues. Please try again later.",
      retry_after = 30,
      circuit_breaker_status = "open"
    }

    kong.response.set_status(503)
    kong.response.set_header("Content-Type", "application/json")
    kong.response.set_header("Retry-After", fallback_response.retry_after)
    kong.response.clear_header("X-Powered-By")
    kong.response.clear_header("Server")

    local fallback_json = require("cjson").encode(fallback_response)
    kong.response.set_raw_body(fallback_json)
  end
end

return CustomFallback

# 6. Advanced Request/Response Processing
# Lua Plugin for Request/Response Transformation
# api-gateway-transformer/handler.lua
local BasePlugin = require "kong.plugins.base_plugin"
local cjson = require "cjson"
local json_decode = cjson.decode
local json_encode = cjson.encode

local ApiGatewayTransformer = BasePlugin:extend()

ApiGatewayTransformer.PRIORITY = 1000
ApiGatewayTransformer.VERSION = "1.0.0"

function ApiGatewayTransformer:new()
  ApiGatewayTransformer.super.new(self, "api-gateway-transformer")
  return self
end

function ApiGatewayTransformer:access(conf)
  -- Extract API version from path
  local path = kong.request.get_path()
  local api_version = path:match("/api/v(%d+)/")

  if api_version then
    kong.ctx.shared.api_version = api_version
    kong.log.info("API version detected: " .. api_version)
  end

  -- Add correlation ID if not present
  local correlation_id = kong.request.get_header("X-Correlation-ID")
  if not correlation_id then
    local uuid = require("resty.uuid")
    local new_id = uuid.generate()
    kong.service.request.set_header("X-Correlation-ID", new_id)
    kong.ctx.shared.correlation_id = new_id
  end

  -- Rate limiting based on user tier
  local user_id = kong.request.get_header("X-User-ID")
  if user_id then
    -- In a real implementation, you would query user data
    local user_tier = "standard"
    if user_id == "premium-user-123" then
      user_tier = "premium"
    end

    kong.ctx.shared.user_tier = user_tier
    kong.log.debug("User " .. user_id .. " tier: " .. user_tier)
  end
end

function ApiGatewayTransformer:body_filter(conf)
  local content_type = kong.response.get_header("Content-Type")

  -- Transform JSON responses
  if content_type and content_type:match("application/json") then
    local body = kong.service.response.get_raw_body()
    if body then
      local success, json_body = pcall(json_decode, body)
      if success then
        -- Add metadata
        local metadata = {
          api_version = kong.ctx.shared.api_version or "unknown",
          gateway_version = "1.0.0",
          response_time = kong.ctx.shared.response_time or 0,
          correlation_id = kong.ctx.shared.correlation_id,
          user_tier = kong.ctx.shared.user_tier or "anonymous"
        }

        json_body._metadata = metadata
        json_body.request_id = kong.ctx.shared.correlation_id

        local transformed_body = json_encode(json_body)
        kong.service.response.set_raw_body(transformed_body)
      end
    end
  end

  -- Set standard response headers
  kong.response.set_header("X-API-Version", kong.ctx.shared.api_version or "unknown")
  kong.response.set_header("X-Correlation-ID", kong.ctx.shared.correlation_id)
  kong.response.set_header("X-Response-Time", (kong.ctx.shared.response_time or 0) .. "ms")
  kong.response.set_header("X-Gateway-Version", "1.0.0")
end

return ApiGatewayTransformer

# 7. Security Hardening
# Request Size Limiting by User Tier
curl -X POST http://localhost:8001/plugins \
  --data 'name=request-size-limiting \
  &config.allowed_payload_size=10 \
  &config.size_unit=mb \
  &config.enforce_uppercase=true \
  &config.client_error_msgs=true \
  &config.exclude=api/internal'

# IP Whitelisting for Admin APIs
curl -X POST http://localhost:8001/services/admin-service/plugins \
  --data 'name=ip-restriction \
  &config.whitelist=10.0.0.0/8,192.168.1.0/24 \
  &config.blacklist=0.0.0.0/0 \
  &config.allowed_methods=GET,POST,PUT,DELETE \
  &config.error_default_message=Forbidden: Your IP is not allowed to access this service

# WAF-like Request Validation
curl -X POST http://localhost:8001/plugins \
  --data 'name=request-validator \
  &config.body_schema="{\"type\": \"object\", \"required\": [\"user_id\"], \"additionalProperties\": false}" \
  &config.status_code=400 \
  &config.error_message=Invalid request body \
  &config.version=2

# 8. Analytics and Business Intelligence
# Analytics Plugin with Custom Metrics
curl -X POST http://localhost:8001/plugins \
  --data 'name=http-log \
  &config.timeout=10000 \
  &config.retry_count=3 \
  &config.buffer_size=4096 \
  &config.flush_timeout=2000 \
  &config.endpoint=http://analytics-collector:3000/events \
  &config.method=POST \
  &config.content_type=application/json \
  &config.custom_fields.user_id=X-User-ID \
  &config.custom_fields.user_tier=X-User-Tier \
  &config.custom_fields.api_version=X-API-Version \
  &config.custom_fields.correlation_id=X-Correlation-ID \
  &config.custom_fields.response_time=X-Response-Time

# Business Metrics Collector
curl -X POST http://localhost:8001/plugins \
  --data 'name=custom-metrics \
  &config.prometheus_metric_prefix=kong_business_ \
  config.metrics.user_requests_total={type="counter", description="Total user requests"}, config.metrics.api_latency={type="histogram", unit="ms", buckets="[10, 50, 100, 250, 500, 1000, 2500, 5000]", description="API latency in milliseconds"}, config.metrics.error_rate={type="gauge", description="Error rate as percentage"}

# 9. Performance Optimization
# Optimized Kong Configuration
# optimized-kong.conf
# Performance settings
nginx_worker_processes auto
nginx_worker_connections 4096

# Buffer sizes
client_body_buffer_size 8k
client_header_buffer_size 4k
client_max_body_size 10m

# Connection timeouts
keepalive_timeout 60s
keepalive_requests 1000
proxy_connect_timeout 60s
proxy_send_timeout 60s
proxy_read_timeout 60s

# Performance plugins
plugins = bundled,cors,jwt,acl,prometheus,custom-metrics

# Optimized plugin settings
prometheus:
  per_consumer: false  # Disable per-consumer metrics for performance
  per_service: true
  per_route: true
  latency_metrics: true
  bandwidth_metrics: false

jwt:
  secret_is_base64: false
  cache_ttl: 300
  access_token_ttl: 3600
  refresh_token_ttl: 604800

# 10. Disaster Recovery and Backup
# Database Backup Configuration
# backup-kong.sh
#!/bin/bash

BACKUP_DIR="/backup/kong"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="kong"

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Database backup
echo "Starting database backup..."
pg_dump -h localhost -U kong -d kong > "$BACKUP_DIR/kong_db_$DATE.sql"

# Declarative configuration backup
echo "Backing up declarative configuration..."
if [ -d "/etc/kong/declarative" ]; then
    tar -czf "$BACKUP_DIR/declarative_config_$DATE.tar.gz" -C /etc/kong/declarative .
fi

# Plugin configurations backup
echo "Backing up plugin configurations..."
docker exec kong tar -czf - /tmp/plugins_$DATE.tar.gz /usr/local/kong/plugins
docker cp kong:/tmp/plugins_$DATE.tar.gz "$BACKUP_DIR/"

# Configuration files backup
echo "Backing up configuration files..."
cp /etc/kong/kong.conf "$BACKUP_DIR/kong_$DATE.conf"

# Cleanup old backups (keep 7 days)
find "$BACKUP_DIR" -name "*.sql" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete

echo "Backup completed: $BACKUP_DIR"
echo "Backup size: $(du -sh $BACKUP_DIR | cut -f1)"