🚪 API Gateway 패턴

패턴 개요

API Gateway는 모든 클라이언트 요청의 **단일 진입점(Single Entry Point)**으로서, 마이크로서비스로의 라우팅, 인증, 로깅, 모니터링 등 공통 기능을 중앙에서 처리하는 아키텍처 패턴입니다.

중요도: ⭐⭐⭐ 필수 패턴

2026년 현재 API Gateway는 MSA의 가장 기본적이면서도 필수적인 패턴으로, 대부분의 현대적인 마이크로서비스 아키텍처에서 표준으로 채택되고 있습니다.


📑 목차


1. 핵심 개념

🎯 정의

API Gateway는 클라이언트와 마이크로서비스 사이에 위치하며, 모든 외부 요청을 먼저 받아서 적절한 서비스로 전달하는 역할을 합니다.

핵심 특징:

  • 단일 진입점: 모든 API 요청이 Gateway를 통과
  • 요청 라우팅: URL, HTTP Method, 헤더 등 기반으로 서비스 선택
  • 크로스 커팅 관심사 처리: 인증, 로깅, 모니터링 등 중앙화
  • 프로토콜 변환: 외부 프로토콜을 내부 서비스 프로토콜로 변환

📊 기본 플로우

Client Requests
       ↓
┌─────────────────┐
│   API Gateway   │ ← 단일 진입점
│                 │
│ - Routing       │
│ - AuthN/AuthZ   │
│ - Rate Limiting │
│ - Logging       │
└─────────────────┘
       ↓
┌─────────────────────────────────────────┐
│           Microservices                │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │Order Svc│ │User Svc │ │Payment  │   │
│  └─────────┘ └─────────┘ │  Svc    │   │
│                      └─────────┘   │
└─────────────────────────────────────────┘

클라이언트 관점의 변화:

Before (Direct Communication):

Client → Order Service
Client → User Service  
Client → Payment Service

After (API Gateway):

Client → API Gateway → (각 서비스)

2. 문제와 해결

🚨 해결하려는 문제

문제 1: 복잡한 클라이언트 로직

직접 통신 방식:

// 클라이언트가 각 서비스를 직접 호출해야 함
const orderResponse = await fetch('https://order-service/api/orders');
const userResponse = await fetch('https://user-service/api/users');
const paymentResponse = await fetch('https://payment-service/api/payments');

문제점:

  • 클라이언트가 여러 서비스의 엔드포인트를 알아야 함
  • 각 서비스의 인증 방식이 다를 경우 처리 복잡
  • 서비스가 추가/변경될 때마다 클라이언트 수정 필요

문제 2: 공통 기능의 중복 구현

Order Service: 인증, 로깅, 모니터링
User Service: 인증, 로깅, 모니터링  
Payment Service: 인증, 로깅, 모니터링

문제점:

  • 각 서비스마다 동일한 코드 중복
  • 보안 정책 일관성 유지 어려움
  • 유지보수 비용 증가

문제 3: 네트워크 보안 및 운영 복잡도

  • 모든 서비스를 외부에 노출해야 함
  • 각 서비스별로 TLS, 인증 설정 필요
  • Rate Limiting, DDoS 방어가 분산됨

✅ API Gateway의 해결 방법

해결 1: 클라이언트 단순화

// 클라이언트는 Gateway만 알면 됨
const response = await fetch('https://api.company.com/orders');
// Gateway가 내부적으로 Order Service로 라우팅
  • 클라이언트는 단일 엔드포인트만 알면 됨
  • 서비스 변경 시 클라이언트 수정 불필요
  • API 버저닝 용이

해결 2: 공통 기능 중앙화

API Gateway
├─ 인증/인가 (모든 요청)
├─ 로깅 (모든 요청)
├─ 모니터링 (모든 요청)
├─ Rate Limiting (모든 요청)
└─ 각 서비스 (비즈니스 로직만)
  • 한 번만 구현하면 모든 서비스에 적용
  • 일관된 정책 적용
  • 유지보수 용이

해결 3: 보안 강화 및 운영 단순화

  • 내부 서비스는 외부에 노출되지 않음
  • Gateway에서 일괄적인 보안 처리
  • DDoS 방어, Rate Limiting 중앙화

3. 아키텍처 구조

📐 전체 아키텍처

┌─────────────────────────────────────────────────────────────┐
│                        External Clients                     │
│  Web App │ Mobile App │ Third Party │ Partner Systems      │
└─────────────────────┬───────────────────────────────────────┘
                      │ HTTPS/WSS
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                      API Gateway                            │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Core Components                          │   │
│  │                                                     │   │
│  │  ┌─────────────┐  ┌──────────────┐  ┌─────────────┐  │   │
│  │  │   Router    │  │    Auth      │  │ Rate Limiter│  │   │
│  │  │             │  │  Service     │  │             │  │   │
│  │  └─────────────┘  └──────────────┘  └─────────────┘  │   │
│  │                                                     │   │
│  │  ┌─────────────┐  ┌──────────────┐  ┌─────────────┐  │   │
│  │  │   Logger    │  │   Monitor    │  │ Transformer │  │   │
│  │  │   Service   │  │   Service    │  │             │  │   │
│  │  └─────────────┘  └──────────────┘  └─────────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────┬───────────────────────────────────────┘
                      │ Internal Network
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                    Microservices                           │
│                                                             │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐         │
│  │Order Service│ │User Service │ │Payment Svc  │   ...     │
│  │             │ │             │ │             │         │
│  │ HTTP/gRPC   │ │ HTTP/gRPC   │ │ HTTP/gRPC   │         │
│  └─────────────┘ └─────────────┘ └─────────────┘         │
└─────────────────────────────────────────────────────────────┘

🔄 요청 처리 플로우 예시

사용자 주문 요청:

1. Client: POST /api/orders
   ↓
2. API Gateway: 인증 확인 (JWT Token)
   ↓
3. API Gateway: Rate Limiting 확인 (초당 100요청)
   ↓
4. API Gateway: 로깅 (요청 메타데이터)
   ↓
5. API Gateway: 라우팅 (/orders → Order Service)
   ↓
6. Order Service: 비즈니스 로직 처리
   ↓
7. API Gateway: 응답 변환 (내부 포맷 → 외부 포맷)
   ↓
8. Client: 주문 생성 완료 응답

4. 핵심 기능들

1️⃣ 요청 라우팅 (Request Routing)

역할: 들어온 요청을 적절한 마이크로서비스로 전달

라우팅 규칙 예시:

# Spring Cloud Gateway 예시
routes:
  - id: order-service
    uri: http://order-service:8080
    predicates:
      - Path=/api/orders/**
      - Method=POST,GET
    
  - id: user-service  
    uri: http://user-service:8080
    predicates:
      - Path=/api/users/**
    
  - id: payment-service
    uri: http://payment-service:8080
    predicates:
      - Path=/api/payments/**
      - Header=X-API-Version=v2

고급 라우팅:

  • Path-based: /api/users/* → User Service
  • Header-based: X-Service: payment → Payment Service
  • Method-based: GET /health → Health Check Service
  • Weight-based: 70% → Service A, 30% → Service B (Canary 배포)

2️⃣ 인증 및 인가 (Authentication & Authorization)

역할: 모든 요청의 보안을 중앙에서 관리

인증 방식:

  • JWT Token: 가장 일반적인 방식
  • API Key: 간단한 시나리오
  • OAuth 2.0: Third-party 접근
  • mTLS: Service-to-service 통신

구현 예시 (Kong):

# Kong 플러그인 설정
services:
  - name: order-service
    url: http://order-service:8080
    plugins:
      - name: jwt
      - name: acl
        config:
          whitelist: [admin, user]
      - name: rate-limiting
        config:
          minute: 100
          hour: 1000

3️⃣ Rate Limiting (속도 제한)

역할: 서비스 보호를 위한 요청 수 제한

제한 전략:

  • IP 기반: 특정 IP의 요청 수 제한
  • User 기반: 로그인 사용자별 제한
  • API Key 기반: 클라이언트별 제한
  • 글로벌: 전체 시스템 제한

예시 설정:

# 다양한 Rate Limiting 전략
rate_limits:
  global:
    requests_per_second: 10000
    
  per_ip:
    requests_per_minute: 100
    burst: 20
    
  per_user:
    premium: 1000/minute
    basic: 100/minute
    
  per_endpoint:
    "/api/orders": 500/minute
    "/api/users": 200/minute

4️⃣ 로깅 및 모니터링 (Logging & Monitoring)

역할: 모든 요청/응답의 가시성 확보

수집 데이터:

  • 요청 메타데이터: IP, User-Agent, Timestamp
  • 성능 메트릭: Latency, Throughput, Error Rate
  • 비즈니스 메트릭: API 사용량, 사용자 패턴

모니터링 대시보드 예시:

API Gateway Dashboard
├─ Total Requests: 1,234,567/hr
├─ Average Latency: 45ms
├─ Error Rate: 0.12%
├─ Top Endpoints:
│  ├─ /api/orders (34%)
│  ├─ /api/users (28%)
│  └─ /api/payments (22%)
└─ Rate Limited IPs: 127

5️⃣ 프로토콜 변환 (Protocol Transformation)

역할: 외부 클라이언트와 내부 서비스 간 프로토콜 변환

변환 예시:

Client (HTTP/JSON) ←→ Gateway ←→ Service (gRPC/Protocol Buffers)
Client (WebSocket) ←→ Gateway ←→ Service (HTTP/REST)
Client (GraphQL)   ←→ Gateway ←→ Service (REST APIs)

GraphQL Gateway 예시:

// 단일 GraphQL 요청을 여러 REST API로 분산
query GetUserOrders($userId: ID!) {
  user(id: $userId) {
    name  // User Service 호출
    email // User Service 호출
  }
  orders(userId: $userId) {
    id    // Order Service 호출
    total // Order Service 호출
  }
}

6️⃣ 캐싱 (Caching)

역할: 반복 요청에 대한 응답을 캐시하여 성능 향상

캐싱 전략:

  • GET 요청: 응답 결과 캐싱
  • 정적 데이터: 사용자 프로필, 제품 정보
  • TTL 기반: 5분, 1시간 등 설정

Redis 캐시 예시:

cache_rules:
  - path: /api/users/*
    method: GET
    ttl: 300  # 5분
    vary_by: [Authorization]
    
  - path: /api/products/*
    method: GET  
    ttl: 3600  # 1시간

5. 실제 구현

🛠️ 기술 스택

상용 제품:

  • Kong: 가장 인기 있는 오픈소스 API Gateway
  • AWS API Gateway: 클라우드 네이티브 솔루션
  • Apigee (Google): 엔터프라이즈급 기능
  • Tyk: 오픈소스 + 상용 hybrid

프레임워크:

  • Spring Cloud Gateway: Java 생태계 표준
  • NGINX + Lua: 고성능 커스텀 Gateway
  • Express.js/Koa: Node.js 기반 경량 Gateway
  • Envoy: Service Mesh와 통합된 고성능 Gateway

💻 Spring Cloud Gateway 예시

1. 의존성 설정

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2. 라우팅 설정

# application.yml
spring:
  cloud:
    gateway:
      routes:
        # 주문 서비스
        - id: order-service
          uri: http://order-service:8080
          predicates:
            - Path=/api/orders/**
            - Method=POST,GET,PUT
          filters:
            - name: CircuitBreaker
              args:
                name: orderCircuitBreaker
                fallbackuri: forward:/fallback/order
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
                
        # 사용자 서비스
        - id: user-service
          uri: http://user-service:8080
          predicates:
            - Path=/api/users/**
          filters:
            - AddRequestHeader=X-Request-Gateway, api-gateway
            - AddResponseHeader=X-Response-Gateway, api-gateway
            
      # 전역 필터
      default-filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20
            key-resolver: "#{@userKeyResolver}"

3. 보안 필터 구현

@Component
public class AuthenticationFilter implements GlobalFilter, Ordered {
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = extractToken(exchange.getRequest());
        
        if (token == null || !jwtTokenUtil.validateToken(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        
        // 사용자 정보를 헤더에 추가
        String userId = jwtTokenUtil.getUserIdFromToken(token);
        ServerHttpRequest modifiedRequest = exchange.getRequest()
            .mutate()
            .header("X-User-Id", userId)
            .build();
            
        return chain.filter(exchange.mutate().request(modifiedRequest).build());
    }
    
    @Override
    public int getOrder() {
        return -100; // 가장 먼저 실행
    }
}

4. 모니터링 엔드포인트

@RestController
@RequestMapping("/actuator")
public class GatewayMonitorController {
    
    @Autowired
    private RouteLocator routeLocator;
    
    @GetMapping("/routes")
    public Flux<Route> routes() {
        return routeLocator.getRoutes();
    }
    
    @GetMapping("/metrics")
    public Map<String, Object> metrics() {
        // Gateway 메트릭 수집
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("totalRequests", getTotalRequests());
        metrics.put("averageLatency", getAverageLatency());
        metrics.put("errorRate", getErrorRate());
        return metrics;
    }
}

🚀 Kong Gateway 예시

1. Kong 설치 및 설정

# Docker로 Kong 실행
docker network create kong-net
 
# Kong Database (PostgreSQL)
docker run -d --name kong-database \
  --network=kong-net \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_PASSWORD=kongpass" \
  -e "POSTGRES_DB=kong" \
  postgres:13
 
# Kong Gateway
docker run -d --name kong-gateway \
  --network=kong-net \
  -p 8000:8000 \
  -p 8001:8001 \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kongpass" \
  -e "KONG_PG_DATABASE=kong" \
  kong:latest

2. 서비스 및 라우트 등록

# 주문 서비스 등록
curl -X POST http://localhost:8001/services \
  --data name=order-service \
  --data url=http://order-service:8080
 
# 주문 서비스 라우트 등록  
curl -X POST http://localhost:8001/services/order-service/routes \
  --data 'paths[]=/api/orders' \
  --data methods[]=POST,GET
 
# JWT 인증 플러그인 활성화
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=jwt
 
# Rate Limiting 플러그인 활성화
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=rate-limiting \
  --data 'config.minute=100' \
  --data 'config.hour=1000'

3. Consumer 설정

# Consumer 생성
curl -X POST http://localhost:8001/consumers \
  --data username=user123
 
# JWT Credential 생성
curl -X POST http://localhost:8001/consumers/user123/jwt
 
# Rate Limiting per Consumer
curl -X POST http://localhost:8001/consumers/user123/plugins \
  --data name=rate-limiting \
  --data 'config.minute=50' \
  --data 'config.hour=500'

6. 장단점

✅ 장점

  1. 클라이언트 단순화

    • 단일 엔드포인트만 알면 됨
    • 서비스 변경 시 클라이언트 영향 없음
    • API 버저닝 용이
  2. 보안 강화

    • 내부 서비스는 외부에 노출되지 않음
    • 중앙화된 인증/인가 관리
    • DDoS 방어, Rate Limiting 용이
  3. 운영 효율성

    • 공통 기능 중앙화로 중복 제거
    • 일관된 로깅, 모니터링
    • 통합된 정책 관리
  4. 확장성

    • 수평적 확장 용이
    • 로드 밸런싱 기본 제공
    • Canary 배포, Blue-Green 배포 지원
  5. 성능 최적화

    • 캐싱으로 응답 시간 개선
    • 요청 압축, 응답 압축
    • Connection Pooling

❌ 단점

  1. 단일 장애점 (SPOF) 위험

    • Gateway 장애 시 전체 서비스 영향
    • 고가용성 구성 필수 (Active-Active, Multi-Region)
  2. 복잡도 증가

    • 라우팅 규칙 복잡성
    • 추가 인프라 운영 필요
    • 성능 튜닝 어려움
  3. 병목 현상 가능성

    • 모든 트래픽이 Gateway 통과
    • 적절한 스케일링과 최적화 필요
    • 비동기 처리로 완화 필요
  4. 개발/배포 복잡성

    • Gateway와 서비스 간 버전 호환성
    • 배포 전략 복잡성
    • 테스트 환경 구성 어려움

7. 사용 시기

✅ 적합한 경우

  1. 다중 클라이언트 환경

    • Web, Mobile, Third-party 등 다양한 클라이언트
    • 각 클라이언트별 API 필요
  2. 마이크로서비스 수 증가

    • 5개 이상의 서비스
    • 서비스 간 통신 복잡성 증가
  3. 보안 및 규제 요구사항

    • 중앙화된 인증/인가 필요
    • 감사 추적, 컴플라이언스 요구
  4. 퍼블릭 API 제공

    • 외부 개발자를 위한 API 제공
    • API Key 관리, Rate Limiting 필요
  5. 글로벌 서비스

    • 다중 리전 배포
    • 지리적 라우팅, CDN 통합

❌ 부적합한 경우

  1. 단일 또는 소수 서비스

    • 2-3개 서비스는 직접 통신이 더 효율적
    • Gateway 오버헤드 > 이점
  2. 단순한 내부 시스템

    • 내부용만 사용
    • 보안 요구사항 낮음
  3. 실시간 저지연 요구

    • 마이크로초(ms) 단위 지연시간 민감
    • Gateway 레이어 제거 필요
  4. 레거시 시스템 통합

    • 기존 시스템과의 통합이 복잡
    • 점진적 전환 필요

8. 2026년 표준 스택

🏆 추천 구성

┌─────────────────────────────────────────────────────────────┐
│                  Load Balancer (L7)                       │
│                   (AWS ALB, GCP LB)                       │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                 API Gateway Cluster                        │
│                                                             │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐         │
│  │Gateway Node1│ │Gateway Node2│ │Gateway Node3│         │
│  │             │ │             │ │             │         │
│  │ Kong/       │ │ Kong/       │ │ Kong/       │         │
│  │ Spring      │ │ Spring      │ │ Spring      │         │
│  │ Cloud       │ │ Cloud       │ │ Cloud       │         │
│  └─────────────┘ └─────────────┘ └─────────────┘         │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                    Supporting Services                      │
│                                                             │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐         │
│  │   Redis     │ │   Prometheus│ │   Jaeger    │         │
│  │   (Cache)   │ │ (Metrics)   │ │ (Tracing)   │         │
│  └─────────────┘ └─────────────┘ └─────────────┘         │
│                                                             │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐         │
│  │    ELK      │ │   Kong      │ │   AWS       │         │
│  │ (Logging)   │ │   Manager   │ │  WAF/Shield │         │
│  └─────────────┘ └─────────────┘ └─────────────┘         │
└─────────────────────────────────────────────────────────────┘

📦 주요 도구

1. API Gateway

  • Kong: 오픈소스 표준, 플러그인 생태계 풍부
  • Spring Cloud Gateway: Java 생태계, 프로그래매틱 설정
  • AWS API Gateway: 서버리스, 관리형 서비스

2. 캐시

  • Redis: 인메모리 캐시, 분산 캐시
  • Memcached: 단순 캐싱, 고성능

3. 모니터링

  • Prometheus + Grafana: 메트릭 수집 및 시각화
  • Jaeger: 분산 트레이싱
  • ELK Stack: 로그 중앙화

4. 보안

  • AWS WAF/Shield: DDoS 방어
  • OAuth 2.0/OpenID Connect: 표준 인증
  • Let’s Encrypt: 무료 TLS 인증서

🚀 2026년 트렌드

  1. 서버리스 Gateway

    • AWS API Gateway, Azure API Management
    • 운영 오버헤드 최소화
  2. AI 기반 보안

    • 머신러닝 기반 Anomaly Detection
    • 자동 DDoS 탐지 및 차단
  3. GraphQL Gateway

    • 단일 엔드포인트, 데이터 집계
    • 클라이언트 드리븐 개발
  4. Edge Computing

    • Cloudflare Workers, Fastly Compute@Edge
    • 전역 분산 처리

9. 실전 사례

🏢 실제 기업 사례

Netflix

규모:

  • 수억 사용자, 전 세계 배포
  • 초당 수십만 API 요청

아키텍처:

Client
  ↓
Zuul Gateway (Netflix OSS)
  ↓
  ├─ Video Service
  ├─ User Service  
  ├─ Recommendation Service
  └─ Billing Service

특징:

  • 자체 개발한 Zuul Gateway 사용
  • Dynamic Routing으로 실시간 서비스 배포
  • Chaos Engineering으로 장애 대비

Uber

사용 사례:

  • 다양한 클라이언트 (Rider, Driver, Partner)
  • 실시간 위치 기반 API

API Gateway 구성:

Mobile Apps
  ↓
API Gateway
  ├─ Rider APIs
  ├─ Driver APIs
  ├─ Payment APIs
  └─ Analytics APIs

성과:

  • API 응답 시간 40% 개선
  • 99.99% 가용성 달성
  • 개발자 생산성 2배 향상

Spotify

특징:

  • 음악 스트리밍, 실시간 처리
  • 다양한 플랫폼 지원

Gateway 활용:

  • 요청 캐싱으로 인기 곡 메타데이터 빠른 응답
  • 사용자별 맞춤형 API 제공
  • A/B 테스트 기반 기능 롤아웃

📊 성능 데이터

API Gateway 도입 전후 비교:

메트릭도입 전도입 후개선율
응답 시간120ms85ms29% ↓
개발 시간3주/기능1주/기능67% ↓
보안 사고5건/월1건/월80% ↓
서비스 가용성99.5%99.95%0.45% ↑

📚 참고 자료

🔗 관련 패턴

📖 추가 학습 자료


상위 문서: 통신 패턴 폴더 마지막 업데이트: 2026-01-05 다음 학습: Service Mesh 패턴


Supported by Claude Sonnet 4.5