---
id: api-gateway-kong-envoy
title: API Gateway — Kong / Envoy / Tyk
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [api, gateway, infrastructure, vibe-coding]
tech_stack: { language: "Lua / YAML", applicable_to: ["Backend", "Infrastructure"] }
applied_in: []
aliases: [API gateway, Kong, Envoy, Tyk, Apigee, Krakend, Traefik]
---

# API Gateway

> 모든 API request 의 entry point. **Auth, rate limit, transform, route, observability** 한 곳. Kong / Envoy / Tyk / Krakend / Apigee.

## 📖 핵심 개념
- L7 proxy + plugins.
- Service discovery + routing.
- Cross-cutting concern (auth, rate, log).
- Backend service 가 비즈니스만.

## 💻 코드 패턴

### Kong (declarative)
```yaml
# kong.yaml
_format_version: "3.0"

services:
  - name: user-api
    url: http://users:8080
    routes:
      - name: user-route
        paths: [/api/users]
    plugins:
      - name: rate-limiting
        config: { minute: 100 }
      - name: jwt
      - name: prometheus
```

```bash
# DB-less mode
kong start -c kong.conf --vv
```

→ DB-less = config file. DB mode = postgres / cassandra.

### Kong Konnect / Enterprise
- Managed control plane
- Multi-region
- Plugin marketplace
- DevPortal

### Envoy (xDS)
```yaml
# envoy.yaml
static_resources:
  listeners:
    - address:
        socket_address: { address: 0.0.0.0, port_value: 8080 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                route_config:
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route: { cluster: backend }
                http_filters:
                  - name: envoy.filters.http.jwt_authn
                  - name: envoy.filters.http.ratelimit
                  - name: envoy.filters.http.router
  clusters:
    - name: backend
      load_assignment:
        cluster_name: backend
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address: { address: backend, port_value: 8080 }
```

→ Istio / service mesh 의 데이터 plane.

### Tyk
```bash
curl -H "X-Tyk-Authorization: $KEY" \
  -X POST http://gateway:8080/tyk/apis \
  -d @api.json

curl -X POST http://gateway:8080/tyk/reload
```

→ API 별 JSON config + hot reload.

### Krakend (declarative, fast)
```json
{
  "version": 3,
  "endpoints": [
    {
      "endpoint": "/api/user/{id}",
      "method": "GET",
      "backend": [
        { "url_pattern": "/users/{id}", "host": ["http://users:8080"] }
      ],
      "extra_config": {
        "qos/ratelimit/router": { "max_rate": 100, "client_max_rate": 10 }
      }
    }
  ]
}
```

→ Aggregator (여러 backend 합쳐 1 response).

### Plugin / filter
```
- Authentication (JWT, OAuth, API key)
- Rate limiting
- Request / response transform
- Logging / tracing
- Caching
- CORS
- Body validation
- IP filtering
- Bot detection
```

### JWT validation (Kong)
```yaml
plugins:
  - name: jwt
    config:
      uri_param_names: [token]
      claims_to_verify: [exp]
```

```bash
# Consumer 등록
curl -X POST http://kong:8001/consumers -d "username=alice"
curl -X POST http://kong:8001/consumers/alice/jwt -d "key=alice-key"
```

### Rate limiting (Kong)
```yaml
plugins:
  - name: rate-limiting
    config:
      second: 5
      minute: 30
      hour: 1000
      policy: redis
      redis_host: redis
```

→ Local (per node) vs cluster (redis).

### Request transform
```yaml
- name: request-transformer
  config:
    add:
      headers: ["X-User: $(jwt.sub)"]
    remove:
      headers: ["Authorization"]
```

### gRPC gateway
```yaml
# Envoy
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.grpc_json_transcoder
  typed_config:
    proto_descriptor: "/etc/proto.pb"
    services: ["user.UserService"]
```

→ gRPC 가 REST / web 으로.

### Canary deploy
```yaml
# Envoy weighted_clusters
routes:
  - match: { prefix: "/" }
    route:
      weighted_clusters:
        clusters:
          - { name: backend-v1, weight: 90 }
          - { name: backend-v2, weight: 10 }
```

→ 10% 트래픽 v2.

### A/B test (header / cookie)
```yaml
routes:
  - match:
      prefix: "/"
      headers: [{ name: "x-user-segment", exact_match: "beta" }]
    route: { cluster: backend-beta }
  - match: { prefix: "/" }
    route: { cluster: backend-prod }
```

### Observability
```
- Access log → ELK / Loki
- Metrics → Prometheus (RED / USE)
- Tracing → Jaeger / Zipkin / OTel
- Audit log (auth events)

→ Gateway 가 모두 한 곳.
```

### Hot reload
```bash
# Envoy
envoy --hot-restart

# Kong
kong reload
```

→ Config 변경 — connection drop X.

### mTLS
```yaml
# Service mesh (Istio + Envoy)
mtls:
  mode: STRICT
```

→ Service-to-service 자동 TLS.

### Header injection (request 추적)
```yaml
- name: correlation-id
  config:
    header_name: X-Request-ID
    generator: uuid
    echo_downstream: true
```

### CORS
```yaml
- name: cors
  config:
    origins: ["https://app.com"]
    methods: ["GET", "POST"]
    credentials: true
    max_age: 3600
```

### Bot / DDoS
```yaml
- name: ip-restriction
  config:
    deny: ["192.168.1.0/24"]

- name: bot-detection
  config:
    deny:
      - "(?i)(bot|crawler|spider)"
```

### Body / response cache
```yaml
- name: proxy-cache
  config:
    response_code: [200]
    request_method: [GET]
    content_type: ["application/json"]
    cache_ttl: 300
    strategy: memory
```

### GraphQL
```yaml
- name: graphql-rate-limiting
  config:
    cost_strategy: node_quantifier  # query complexity
    max_cost: 1000
```

### AWS API Gateway
```yaml
# Serverless framework
functions:
  api:
    handler: handler.api
    events:
      - http:
          path: users/{id}
          method: get
          cors: true
          authorizer: aws_iam
```

→ Managed, Lambda 친화. 큰 traffic 비쌈.

### Cloudflare Workers + WAF
```ts
// Cloudflare Worker = edge gateway
export default {
  async fetch(req: Request) {
    if (await isBot(req)) return new Response('blocked', { status: 403 });
    return fetch('https://backend' + new URL(req.url).pathname, req);
  },
};
```

→ Edge 의 가벼운 gateway.

### NGINX (간단 gateway)
```nginx
upstream backend { server backend:8080; }

location /api/ {
    auth_jwt "Realm" token=$arg_token;
    auth_jwt_key_file /etc/nginx/jwt.key;
    
    limit_req zone=api burst=10;
    proxy_pass http://backend/;
}
```

→ NGINX Plus = enterprise feature.

### Service mesh vs gateway
```
Gateway: north-south (외부 → 내부)
Service mesh: east-west (서비스 간)

→ 큰 system 가 둘 다.
Service mesh = Istio / Linkerd / Consul.
```

### Custom gateway (Hono / Bun)
```ts
import { Hono } from 'hono';
const app = new Hono();

app.use('*', async (c, next) => {
  // JWT validate
  const token = c.req.header('authorization')?.replace('Bearer ', '');
  if (!verifyJwt(token)) return c.text('unauthorized', 401);
  await next();
});

app.use('*', rateLimit({ max: 100, window: 60 }));

app.all('/api/users/*', async (c) => {
  return fetch('http://users:8080' + c.req.path, c.req.raw);
});
```

→ 작은 / 특화 gateway.

### Cost / 선택
```
Kong: 큰 ecosystem, 가장 인기
Envoy: 가장 빠름, complex config
Tyk: 좋은 UI, dashboard
Krakend: simple, 빠름, declarative
Traefik: K8s 친화, automatic
NGINX: legacy 강함
AWS API Gateway: serverless 친화
Cloudflare: edge
```

## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| 일반 API | Kong / Tyk |
| 가장 빠름 | Envoy / Krakend |
| Service mesh | Istio (Envoy) |
| K8s 친화 | Traefik / Kong K8s |
| Serverless | AWS API Gateway |
| Edge | Cloudflare Workers |
| 작은 / custom | Hono / NGINX |
| Aggregator | Krakend / Apollo gateway |

## ❌ 안티패턴
- **모든 logic 가 gateway**: 비즈니스 분리.
- **No rate limit**: DDoS 취약.
- **No auth at gateway**: 매 service 다.
- **Hot reload 없음**: 매번 down.
- **No observability**: blind.
- **DB mode + single Postgres**: SPOF.
- **Plugin 너무 많음**: latency 누적.

## 🤖 LLM 활용 힌트
- Kong / Envoy 가 default 후보.
- Auth + rate + log = baseline plugin.
- Hot reload 필수 (zero-downtime).
- Service mesh 가 east-west.

## 🔗 관련 문서
- [[Backend_API_Gateway_BFF]]
- [[DevOps_Service_Mesh_Deep]]
- [[Backend_Rate_Limiting]]
