Amazon API Gateway 정리
작성자 : 오예환 | 작성일 : 2026-01-18 | 수정일 : 2026-01-18
1. API Gateway 개요
🤔 API Gateway가 뭔가요?
비유로 이해하기: API Gateway는 레스토랑의 웨이터와 같습니다.
- 손님(클라이언트)이 주문(요청)을 하면
- 웨이터(API Gateway)가 주문을 받아서
- 주방(백엔드 서버/Lambda)에 전달하고
- 요리(응답)를 다시 손님에게 가져다줍니다
웨이터가 없으면 손님이 직접 주방에 가야 하는데, 이건 비효율적이고 주방이 복잡해지겠죠? API Gateway도 마찬가지로 클라이언트와 백엔드 사이에서 중간 역할을 합니다.
Serverless API 아키텍처
Client → API Gateway → Lambda → DynamoDB
(REST API) (PROXY) (CRUD)설명:
- Client: 웹 브라우저, 모바일 앱 등 사용자가 사용하는 프로그램
- API Gateway: 요청을 받아서 적절한 곳으로 전달하는 "교통 경찰"
- Lambda: 실제 비즈니스 로직을 처리하는 "일꾼"
- DynamoDB: 데이터를 저장하는 "창고"
주요 기능
| 기능 | 설명 | 설명 |
|---|---|---|
| 인프라 관리 불필요 | Lambda + API Gateway | 서버 설치/관리 안 해도 됨 |
| WebSocket | 실시간 양방향 통신 | 채팅처럼 즉각 응답 가능 |
| API 버전 관리 | v1, v2, ... | 새 기능 추가해도 기존 사용자 영향 없음 |
| 환경 분리 | dev, test, prod | 개발/테스트/실제 서비스 분리 |
| 보안 | 인증, 인가 | 누가 API를 쓸 수 있는지 제어 |
| API 키 & Throttling | 요청 제한 | 과도한 요청 방지 (DDoS 등) |
| Swagger/OpenAPI | API 정의 가져오기 | API 문서를 코드로 관리 |
| 요청/응답 변환 | Mapping Templates | 데이터 형식 변환 (JSON-XML) |
| SDK 생성 | API 명세 자동 생성 | 클라이언트 코드 자동 생성 |
| 응답 캐싱 | 백엔드 호출 감소 | 같은 요청은 저장해둔 답변 재사용 |
2. Integration Types (통합 유형)
🤔 Integration이 뭔가요?
비유로 이해하기: API Gateway가 받은 요청을 어디로, 어떻게 전달할지 결정하는 것입니다.
- 마치 콜센터에서 전화를 받으면 "어느 부서로 연결해드릴까요?"라고 묻는 것처럼
- API Gateway도 요청을 Lambda로 보낼지, 다른 HTTP 서버로 보낼지, AWS 서비스로 보낼지 결정합니다.
백엔드 통합 옵션
| 통합 | 설명 | 실제 사용 예시 |
|---|---|---|
| Lambda Function | Lambda 호출 (가장 일반적) | 회원가입 처리, 데이터 조회 |
| HTTP | 내부 HTTP API, ALB | 기존 서버와 연동 |
| AWS Service | AWS 서비스 직접 노출 | S3 파일 업로드, SQS 메시지 전송 |
AWS Service 통합 예시
Client → API Gateway → Kinesis Data Streams → Kinesis Data Firehose → S3
(requests) (send records) (.json 저장)설명: Lambda 없이도 API Gateway가 직접 AWS 서비스를 호출할 수 있습니다. 예를 들어, 클릭 로그를 S3에 저장하고 싶다면:
- 사용자가 클릭 → API Gateway로 요청
- API Gateway가 직접 Kinesis로 데이터 전송
- Kinesis가 S3에 파일로 저장
Lambda 비용을 아낄 수 있어요!
3. Integration Types 상세
🤔 왜 여러 종류가 있나요?
상황에 따라 필요한 기능이 다르기 때문입니다:
- 간단한 Lambda 호출 → AWS_PROXY (가장 쉬움)
- 데이터 형식 변환 필요 → AWS/HTTP (Mapping 사용)
- 테스트/목업 → MOCK
MOCK
Client → API Gateway → (백엔드 없음) → 미리 정의된 응답 반환설명: 아직 백엔드가 준비 안 됐을 때 테스트용으로 사용합니다. 예: 프론트엔드 개발자가 백엔드 완성 전에 가짜 응답으로 먼저 개발
{
"message": "Hello, this is a mock response!",
"status": "success"
}HTTP / AWS (Lambda & AWS Services)
Client → API Gateway + Mapping Templates → SQS Queue설명: 요청/응답 데이터를 변환해야 할 때 사용합니다. 예: 클라이언트는 JSON으로 보내는데, 백엔드는 XML을 원할 때
클라이언트: { "name": "홍길동" }
↓ (Mapping Template으로 변환)
백엔드: <user><name>홍길동</name></user>AWS_PROXY (Lambda Proxy) ⭐ 가장 많이 사용!
Client Request → API Gateway → Lambda (그대로 전달)
│
├─ 요청/응답 로직은 Lambda가 처리
└─ Mapping Template 없음설명: API Gateway가 받은 요청을 아무 가공 없이 Lambda에 전달합니다.
- 장점: 설정이 간단함, Lambda에서 모든 것을 처리
- 단점: Lambda 코드에서 직접 헤더, 쿼리 파라미터 등을 파싱해야 함
Lambda가 받는 event 객체 예시:
def lambda_handler(event, context):
# event에 모든 정보가 담겨 옴
print(event['headers']) # HTTP 헤더
print(event['queryStringParameters']) # ?name=value
print(event['body']) # POST 본문
return {
'statusCode': 200,
'body': '{"message": "success"}'
}HTTP_PROXY
Client → API Gateway → HTTP Backend (그대로 전달)설명: 기존에 운영 중인 HTTP 서버가 있을 때 사용합니다. 예: 회사 내부에 이미 Express.js 서버가 있는데, API Gateway를 앞에 붙여서 인증/제한 기능만 추가하고 싶을 때
기존: Client ──→ Express Server
변경: Client ──→ API Gateway (인증, 제한) ──→ Express Server4. Endpoint Types
🤔 Endpoint가 뭔가요?
비유로 이해하기: API Gateway의 **"입구 위치"**를 결정합니다.
- 전 세계 고객 대상 → 여러 나라에 입구(Edge) 설치
- 한국 고객만 대상 → 서울에만 입구(Regional) 설치
- 회사 내부용 → 회사 건물 안에만 입구(Private) 설치
| 유형 | 설명 | 언제 사용? |
|---|---|---|
| Edge-Optimized (기본) | CloudFront Edge 경유, 글로벌 클라이언트용 | 전 세계 사용자 대상 서비스 |
| Regional | 같은 리전 클라이언트용 | 특정 지역만 대상 (예: 한국 서비스) |
| Private | VPC 내에서만 접근 | 회사 내부 API, 보안 중요 시스템 |
HTTPS 인증서 위치
| Endpoint | 인증서 위치 | 이유 |
|---|---|---|
| Edge-Optimized | us-east-1 | CloudFront가 us-east-1 인증서만 사용 |
| Regional | API Gateway 리전 | 해당 리전에서 직접 처리 |
주의사항: Edge-Optimized를 쓰는데 인증서를 서울(ap-northeast-2)에 만들면 작동 안 해요! 반드시 **버지니아(us-east-1)**에 인증서를 만들어야 합니다.
💡 Route 53에 CNAME 또는 A-Alias 레코드 설정 필요
예:
api.mycompany.com→ API Gateway 주소
5. Deployment & Stages
🤔 왜 Deployment가 필요한가요?
비유로 이해하기: 문서 편집 프로그램에서 "저장" 버튼을 누르는 것과 같습니다.
- 문서를 수정해도 저장 안 하면 반영 안 되죠?
- API Gateway도 마찬가지로 변경 후 Deployment를 해야 적용됩니다.
배포 개념
API Gateway 변경 → 바로 적용 ❌
→ "Deployment" 필요 ✅ → Stage에 배포⚠️ 가장 흔한 실수: "설정 바꿨는데 왜 안 되지?" → Deployment 안 해서!
Stage란?
비유로 이해하기: 게임의 서버와 같습니다.
- 테스트 서버(dev): 개발자들이 테스트
- 공개 테스트 서버(test): 베타 테스터가 테스트
- 정식 서버(prod): 실제 사용자가 사용
v1 Stage ← v1 Client (https://api.example.com/v1)
v2 Stage ← v2 Client (https://api.example.com/v2)실제 사용 예시:
개발 중: https://api.example.com/dev/users
테스트: https://api.example.com/test/users
실서비스: https://api.example.com/prod/users각 Stage는:
- 환경별 분리: 서로 영향 없음
- Stage별 설정 가능: dev는 로깅 많이, prod는 캐싱 활성화
- 롤백 가능: 문제 생기면 이전 버전으로 복구
6. Stage Variables
🤔 Stage Variables가 뭔가요?
비유로 이해하기: 환경 변수와 같습니다. 프로그래밍할 때 DATABASE_URL을 환경별로 다르게 설정하듯이, API Gateway도 Stage별로 다른 값을 설정할 수 있습니다.
사용 위치
- Lambda Function ARN
- HTTP Endpoint
- Parameter Mapping Templates
형식
${stageVariables.variableName}실제 사용 예시
상황: dev 환경은 테스트 Lambda를, prod 환경은 실제 Lambda를 호출하고 싶다
설정:
dev Stage:
lambdaAlias = "DEV"
prod Stage:
lambdaAlias = "PROD"API Gateway 설정:
Lambda ARN: arn:aws:lambda:...:myFunction:${stageVariables.lambdaAlias}결과:
- dev로 요청 →
myFunction:DEV호출 - prod로 요청 →
myFunction:PROD호출
Lambda Alias 연동 (실무 필수 패턴!)
┌─────────────────────────────────────────────────────────────┐
│ │
│ Prod Stage ──→ PROD Alias ──→ V1 (95%) + V2 (5%) │
│ Test Stage ──→ TEST Alias ──→ V2 (100%) │
│ Dev Stage ──→ DEV Alias ──→ $LATEST (100%) │
│ │
└─────────────────────────────────────────────────────────────┘장점: API Gateway 설정 변경 없이 Lambda 버전만 바꿔서 배포 가능!
7. Canary Deployment
🤔 Canary Deployment가 뭔가요?
비유로 이해하기: 옛날 광부들이 카나리아 새를 광산에 먼저 보내서 가스가 있는지 확인했습니다. 소프트웨어에서도 새 버전을 일부 사용자에게만 먼저 배포해서 문제가 없는지 확인합니다.
동작 방식
Client ─┬──(95%)──→ Prod Stage v1 (기존 안정 버전)
│
└──(5%)───→ Prod Stage Canary v2 (새 버전)시나리오:
- 새 기능 개발 완료
- 5% 사용자에게만 새 버전 배포
- 에러율, 성능 모니터링
- 문제 없으면 → 100%로 확대
- 문제 있으면 → 0%로 롤백
특징
- 메트릭 & 로그 분리 (모니터링 용이)
- Stage Variables 오버라이드 가능
- Blue/Green 배포 (Lambda + API Gateway)
팁: 처음엔 무섭지만, 실서비스에서는 필수입니다! 전체 사용자에게 버그가 퍼지는 것보다 5%만 영향받는 게 훨씬 낫죠.
8. Mapping Templates
🤔 Mapping Templates가 뭔가요?
비유로 이해하기: 통역사와 같습니다.
- 클라이언트는 한국어(JSON)로 말하고
- 백엔드는 영어(XML)를 원하면
- Mapping Template이 통역해줍니다
용도 (AWS & HTTP Integration만 해당)
- 요청/응답 수정
- 쿼리 스트링 파라미터 이름 변경
- Body 내용 수정
- 헤더 추가
- 결과 필터링
VTL (Velocity Template Language)
#set($inputRoot = $input.path('$'))
{
"user_name": "$inputRoot.name",
"user_age": $inputRoot.age
}설명: VTL은 약간 낯설 수 있지만, 간단한 문법입니다.
#set= 변수 설정$input.path('$')= 입력 데이터 가져오기$변수명= 변수 사용
예시: Query String → JSON
요청:
GET http://example.com/users?name=홍길동&age=25Mapping Template:
{
"userName": "$input.params('name')",
"userAge": $input.params('age')
}Lambda가 받는 데이터:
{
"userName": "홍길동",
"userAge": 25
}예시: JSON → XML (SOAP 통합)
상황: 클라이언트는 최신 REST API를 쓰는데, 백엔드가 오래된 SOAP(XML) 시스템
Client (REST, JSON) → API Gateway + Mapping Template → SOAP API (XML)이럴 때 사용: 레거시 시스템 연동할 때 유용합니다.
9. OpenAPI Spec
🤔 OpenAPI가 뭔가요?
비유로 이해하기: API의 설계도/도면입니다. 건물을 지을 때 도면이 있듯이, API도 설계도가 있으면:
- 프론트엔드/백엔드 개발자가 같은 문서를 보고 개발
- 자동으로 문서 생성
- 자동으로 SDK(클라이언트 코드) 생성
예시 (YAML 형식)
openapi: 3.0.0
info:
title: 사용자 API
version: 1.0.0
paths:
/users:
get:
summary: 사용자 목록 조회
responses:
"200":
description: 성공
post:
summary: 사용자 생성
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
email:
type: stringAPI Gateway에서의 활용
- 가져오기: OpenAPI 파일로 API Gateway 자동 설정
- 내보내기: 현재 API를 OpenAPI 파일로 저장
- SDK 생성: JavaScript, Python 등 클라이언트 코드 자동 생성
팁: Swagger(OpenAPI의 옛날 이름)를 써본 적 있다면 같은 것입니다!
10. Request Validation
🤔 Request Validation이 뭔가요?
비유로 이해하기: 입장 전 검표와 같습니다. 놀이공원 입장 시 티켓을 확인하듯이, API Gateway가 요청을 검사해서 잘못된 요청은 백엔드까지 가지 않고 바로 거부합니다.
왜 필요한가요?
검증 없을 때:
잘못된 요청 → API Gateway → Lambda (실행됨, 비용 발생) → 에러 반환검증 있을 때:
잘못된 요청 → API Gateway (검증 실패, 400 에러) → Lambda 실행 안 됨!장점: Lambda 비용 절약, 불필요한 백엔드 부하 감소
검증 항목
| 검증 대상 | 예시 |
|---|---|
| 필수 파라미터 | ?userId=가 없으면 거부 |
| 헤더 | Authorization 헤더 없으면 거부 |
| JSON Schema | body가 스키마와 맞지 않으면 거부 |
실제 사용 예시
OpenAPI로 검증 설정:
paths:
/users:
post:
parameters:
- name: Authorization
in: header
required: true # 필수!
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- email # 필수 필드!
properties:
name:
type: string
minLength: 1
email:
type: string
format: email11. Caching
🤔 API 캐싱이 뭔가요?
비유로 이해하기: 메모와 같습니다. 누군가 같은 질문을 계속 하면, 매번 조사하지 않고 메모해둔 답을 바로 알려주는 것처럼 API Gateway도 같은 요청에 대해 저장해둔 응답을 바로 반환합니다.
캐싱 동작 방식
첫 번째 요청:
Client → API Gateway → (캐시 없음) → Lambda → 응답 → 캐시에 저장
두 번째 같은 요청:
Client → API Gateway → (캐시 있음!) → 캐시된 응답 반환 (Lambda 호출 안 함!)설정
| 항목 | 값 | 설명 |
|---|---|---|
| 기본 TTL | 300초 (5분) | 캐시 유지 시간 |
| 최소/최대 | 0초 ~ 3600초 | 0이면 캐싱 안 함 |
| 용량 | 0.5GB ~ 237GB | 저장 공간 |
| 암호화 | 옵션 | 민감한 데이터용 |
⚠️ 캐시는 비쌈 → 프로덕션에서만 사용 권장
비용 예시 (2024년 기준):
- 0.5GB 캐시: 약 $14/월
- 6.1GB 캐시: 약 $237/월
Cache Invalidation (캐시 무효화)
상황: 데이터가 바뀌었는데 캐시에 옛날 데이터가 남아있다면?
| 방법 | 사용법 |
|---|---|
| 콘솔 | 버튼 클릭으로 전체 캐시 삭제 |
| 클라이언트 | Cache-Control: max-age=0 헤더 |
⚠️ 주의: 정책 설정 안 하면 아무나 캐시 무효화 가능!
12. Usage Plans & API Keys
🤔 이게 왜 필요한가요?
비유로 이해하기: 헬스장 회원권과 같습니다.
- 무료 회원: 하루 1시간, 러닝머신만
- 골드 회원: 하루 3시간, 모든 기구
- VIP 회원: 무제한, 개인 트레이너 포함
API도 마찬가지로 고객별로 사용량과 기능을 다르게 할 수 있습니다.
Usage Plan
| 항목 | 설명 | 예시 |
|---|---|---|
| 용도 | API를 유료 서비스로 제공 | SaaS API |
| 정의 | 누가, 어느 API에 접근 가능 | Free 플랜은 /basic만, Pro는 전체 |
| Throttling | 초당 요청 제한 | Free: 10 RPS, Pro: 100 RPS |
| Quota | 월간 총 요청 제한 | Free: 1000회/월, Pro: 100,000회/월 |
API Keys
x-api-key: WBjHxNtoAb4WPKBC7cGm64CBibIb24b4jt8jJHo9설명: API Key는 비밀번호와 같습니다. 고객에게 발급해주고, 요청 시 헤더에 포함해야 합니다.
설정 순서 (시험에 자주 나옴!)
1단계: API 생성 → 메서드에 "API Key 필요" 설정 → Stage 배포
2단계: API Keys 생성 (고객에게 배포)
3단계: Usage Plan 생성 (Throttle, Quota 설정)
4단계: Usage Plan에 API Stages + API Keys 연결실제 요청 예시:
curl -X GET "https://api.example.com/prod/users" \
-H "x-api-key: WBjHxNtoAb4WPKBC7cGm64CBibIb24b4jt8jJHo9"13. Logging & Monitoring
🤔 왜 로깅이 중요한가요?
비유로 이해하기: CCTV/블랙박스와 같습니다. 문제가 생겼을 때 "언제, 누가, 무슨 요청을 했는지" 확인할 수 있어야 합니다.
CloudWatch Logs
| 설정 | 설명 |
|---|---|
| 활성화 위치 | Stage 레벨 |
| 로그 레벨 | ERROR, DEBUG, INFO |
| 내용 | 요청/응답 Body, 헤더 등 |
로그 예시:
[INFO] Request: GET /users?page=1
[INFO] Headers: { "x-api-key": "***", "Content-Type": "application/json" }
[INFO] Response: 200, Body: {"users": [...]}
[ERROR] Request: POST /users - 500 Internal Server ErrorX-Ray
설명: CloudWatch Logs가 텍스트 기록이라면, X-Ray는 시각적 추적입니다. 요청이 어디서 얼마나 시간이 걸렸는지 그래프로 보여줍니다.
Client → API Gateway (10ms) → Lambda (200ms) → DynamoDB (50ms)
│
└─→ 어디가 병목인지 한눈에!CloudWatch Metrics (주요 지표)
| 메트릭 | 설명 | 사용 |
|---|---|---|
CacheHitCount | 캐시 히트 수 | 캐시 효율성 확인 |
CacheMissCount | 캐시 미스 수 | 캐시 효율성 확인 |
Count | 총 API 요청 수 | 트래픽 모니터링 |
IntegrationLatency | 백엔드 응답 시간 | Lambda 성능 확인 |
Latency | 전체 응답 시간 | 사용자 체감 속도 |
4XXError | 클라이언트 에러 | 잘못된 요청 모니터링 |
5XXError | 서버 에러 | 시스템 문제 감지 |
14. Throttling
🤔 Throttling이 뭔가요?
비유로 이해하기: 고속도로 진입 제한과 같습니다. 차가 너무 많으면 고속도로가 막히듯이, API 요청이 너무 많으면 서버가 죽을 수 있습니다. 그래서 "초당 최대 100대만 진입 가능"처럼 제한을 겁니다.
Account Limit (기본 제한)
| 항목 | 값 |
|---|---|
| 기본 제한 | 10,000 RPS (초당 요청) |
| 유형 | Soft limit (AWS에 요청하면 증가 가능) |
| 에러 코드 | 429 Too Many Requests |
Throttle 발생 시
Client → API Gateway → "429 Too Many Requests"
"잠시 후 다시 시도하세요"클라이언트 대응:
- 에러 받으면 잠시 대기
- 재시도 (Exponential Backoff: 1초 → 2초 → 4초...)
제한 설정 레벨
Account (10,000 RPS)
│
├─ Stage limit (예: prod는 5,000 RPS)
│ │
│ └─ Method limit (예: POST /orders는 1,000 RPS)
│
└─ Usage Plan (고객별)
│
├─ Free 고객: 10 RPS
└─ Pro 고객: 100 RPS⚠️ 주의: 하나의 API가 모든 한도를 써버리면 다른 API도 Throttle!
예시: /download API가 10,000 RPS를 다 쓰면 /login API도 429 에러
15. Error Codes
🤔 에러 코드를 왜 알아야 하나요?
문제가 생겼을 때 에러 코드를 보면 원인을 빠르게 파악할 수 있습니다.
4XX (클라이언트 에러) - "사용자가 잘못함"
| 코드 | 의미 | 해결 방법 |
|---|---|---|
| 400 | Bad Request | 요청 형식 확인 (JSON 오류 등) |
| 403 | Access Denied | 인증/권한 확인 |
| 429 | Too Many Requests | 잠시 후 재시도 |
5XX (서버 에러) - "서버가 잘못함"
| 코드 | 의미 | 원인 |
|---|---|---|
| 502 | Bad Gateway | Lambda 응답 형식 오류, 과부하 |
| 503 | Service Unavailable | 서비스 일시 중단 |
| 504 | Gateway Timeout | 백엔드가 29초 내 응답 안 함 |
502 에러 자주 발생하는 경우
Lambda Proxy Integration에서 잘못된 응답 형식:
# 잘못된 응답 (502 발생!)
def lambda_handler(event, context):
return "Hello"
# 올바른 응답
def lambda_handler(event, context):
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': '{"message": "Hello"}'
}⚠️ 중요: API Gateway 타임아웃은 최대 29초!
Lambda가 30초 이상 걸리면 무조건 504 에러
16. CORS
🤔 CORS가 뭔가요?
비유로 이해하기: 방문증과 같습니다. A 회사 건물에서 B 회사 건물로 가려면 방문증이 필요하듯이, 웹 브라우저에서 다른 도메인의 API를 호출하려면 허가가 필요합니다.
왜 필요한가요?
상황:
- 프론트엔드:
https://www.mysite.com - API:
https://api.mysite.com
브라우저는 보안상 다른 도메인으로 요청하는 것을 기본적으로 차단합니다. CORS 설정을 통해 "이 도메인은 허용"이라고 알려줘야 합니다.
동작 방식
1. 브라우저: "api.mysite.com으로 요청해도 될까요?" (OPTIONS 요청)
2. API Gateway: "www.mysite.com은 허용됩니다" (CORS 헤더 응답)
3. 브라우저: "허가받았으니 실제 요청 보냄" (GET/POST 요청)필요 헤더
| 헤더 | 설명 | 예시 |
|---|---|---|
Access-Control-Allow-Origin | 허용할 도메인 | https://www.mysite.com |
Access-Control-Allow-Methods | 허용할 메서드 | GET, POST, PUT, DELETE |
Access-Control-Allow-Headers | 허용할 헤더 | Content-Type, Authorization |
설정 방법
API Gateway 콘솔에서 버튼 클릭으로 쉽게 설정 가능!
실수하기 쉬운 점:
- Lambda에서도 CORS 헤더를 반환해야 함 (Proxy Integration 시)
def lambda_handler(event, context):
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
},
'body': '{"message": "success"}'
}17. Security - 인증 & 인가
🤔 인증 vs 인가?
| 용어 | 의미 | 비유 |
|---|---|---|
| 인증 (Authentication) | "너 누구야?" | 신분증 확인 |
| 인가 (Authorization) | "너 이거 해도 돼?" | 출입 권한 확인 |
IAM Permissions
Client (AWS 내부) → API Gateway → Backend
│
└─ IAM 자격 증명 + Signature v4 서명설명: AWS 서비스끼리 통신할 때 사용합니다. 예: EC2에서 API Gateway 호출, Lambda에서 다른 API Gateway 호출
| 항목 | 설명 |
|---|---|
| 인증 | IAM (AWS 자격 증명) |
| 인가 | IAM Policy ("이 API 호출 가능") |
| 용도 | AWS 내부 (EC2, Lambda, IAM 사용자) |
Resource Policies
설명: S3 버킷 정책처럼 "누가 이 API Gateway에 접근할 수 있는지" 정의합니다.
사용 사례:
- 다른 AWS 계정에서 접근 허용
- 특정 IP만 허용 (예: 회사 IP만)
- VPC Endpoint에서만 접근 허용
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:...",
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}Cognito User Pools
1. 사용자 → Cognito 로그인 → 토큰 받음
2. 사용자 → API Gateway (토큰 포함) → Cognito 토큰 검증 → Backend설명: 모바일 앱이나 웹사이트에서 일반 사용자 로그인할 때 사용합니다. Facebook/Google 로그인도 Cognito로 연동 가능!
| 항목 | 설명 |
|---|---|
| 인증 | Cognito (이메일/비밀번호, 소셜 로그인) |
| 인가 | API Gateway Methods |
| 장점 | 코드 작성 불필요! |
Lambda Authorizer
1. 사용자 → API Gateway (토큰 포함)
2. API Gateway → Lambda Authorizer 호출
3. Lambda → 토큰 검증 (회사 자체 인증 서버 확인)
4. Lambda → IAM Policy 반환 ("이 사용자는 /users만 접근 가능")
5. API Gateway → Backend 호출 또는 거부설명: 회사에서 자체 인증 시스템을 쓰거나, JWT 토큰을 직접 검증하고 싶을 때 사용합니다.
| 항목 | 설명 |
|---|---|
| 인증 | 외부 (JWT, OAuth, 자체 시스템) |
| 인가 | Lambda 함수가 결정 |
| 비용 | Lambda 호출당 과금 |
| 최적화 | 결과 캐시 가능 (매번 Lambda 호출 안 해도 됨) |
18. Security 요약
언제 무엇을 써야 할까요?
| 상황 | 추천 방식 |
|---|---|
| AWS 내부 서비스 간 통신 | IAM |
| 모바일 앱/웹 일반 사용자 | Cognito |
| 자체 인증 시스템 사용 | Lambda Authorizer |
| 특정 IP만 허용 | Resource Policy |
비교표
| 방식 | 인증 | 인가 | 용도 | 코드 필요 |
|---|---|---|---|---|
| IAM | IAM | IAM Policy | AWS 내부 | ❌ |
| Cognito | Cognito | API Gateway | 외부 사용자 | ❌ |
| Lambda Authorizer | 외부 | Lambda | 3rd Party | ✅ |
19. HTTP API vs REST API
🤔 둘 다 API인데 뭐가 다른가요?
비유로 이해하기:
- HTTP API = 경차: 저렴하고 기본 기능만
- REST API = SUV: 비싸지만 모든 기능 포함
비교표
| 항목 | HTTP API | REST API |
|---|---|---|
| 비용 | 저렴 (최대 71% 절감) | 비쌈 |
| 지연시간 | 낮음 | 일반 |
| 기능 | 최소 | 모든 기능 |
| Mapping Templates | ❌ | ✅ |
| Usage Plans/API Keys | ❌ | ✅ |
| 캐싱 | ❌ | ✅ |
| Request Validation | ❌ | ✅ |
| Resource Policies | ❌ | ✅ |
| OIDC/OAuth 2.0 | ✅ (네이티브) | ❌ |
언제 무엇을 쓸까?
| 상황 | 추천 |
|---|---|
| Lambda Proxy만 필요 | HTTP API |
| 비용 최적화 중요 | HTTP API |
| API Key/Usage Plan 필요 | REST API |
| 캐싱, Request Validation 필요 | REST API |
| 복잡한 변환 필요 | REST API |
팁: 처음에는 HTTP API로 시작하고, 기능이 부족하면 REST API로 전환하세요!
20. WebSocket API
🤔 WebSocket이 뭔가요?
비유로 이해하기:
- 일반 HTTP: 전화 한 통화 (요청-응답 후 끊김)
- WebSocket: 통화 유지 (계속 대화 가능)
일반 HTTP vs WebSocket
| 항목 | HTTP | WebSocket |
|---|---|---|
| 연결 | 요청마다 새로 | 한 번 연결, 계속 유지 |
| 방향 | 클라이언트에서 서버로만 | 양방향 |
| 서버 푸시 | ❌ (Polling 필요) | ✅ |
| 용도 | 일반 API | 실시간 앱 |
사용 사례
| 사례 | 설명 |
|---|---|
| 채팅 앱 | 메시지 즉시 전달 |
| 주식 시세 | 실시간 가격 업데이트 |
| 멀티플레이어 게임 | 플레이어 위치 동기화 |
| 협업 툴 | Google Docs처럼 동시 편집 |
아키텍처
┌─────────────────────────────────────────────────────────────┐
│ CHAT APPLICATION │
│ │
│ [유저A] ←──────────(WebSocket)──────────→ API Gateway │
│ [유저B] ←──────────(WebSocket)──────────→ │ │
│ │ │
│ ┌─────────────────────────┘ │
│ │ │
│ onConnect ────┼──── sendMessage ──── onDisconnect │
│ │ │ │ │ │
│ ▼ │ ▼ ▼ │
│ Lambda │ Lambda Lambda │
│ │ │ │ │ │
│ └────────┴──────────┴────────────────┘ │
│ │ │
│ ▼ │
│ DynamoDB │
│ (connectionId 저장) │
└─────────────────────────────────────────────────────────────┘동작 흐름
1. 연결 (onConnect):
유저A 접속 → connectionId: "abc123" 생성 → DynamoDB에 저장2. 메시지 전송 (sendMessage):
유저A: "안녕하세요!"
→ Lambda: DynamoDB에서 모든 connectionId 조회
→ Lambda: 유저B의 connectionId("xyz789")로 메시지 전송
유저B: "안녕하세요!" 수신3. 연결 해제 (onDisconnect):
유저A 나감 → connectionId: "abc123" 삭제서버 → 클라이언트 메시지 전송
import boto3
# API Gateway Management API 사용
client = boto3.client('apigatewaymanagementapi',
endpoint_url='https://abcdef.execute-api.us-west-1.amazonaws.com/dev')
# 특정 클라이언트에게 메시지 전송
client.post_to_connection(
ConnectionId='abc123',
Data=b'{"message": "Hello from server!"}'
)21. API Gateway Architecture
🤔 실제로 어떻게 구성하나요?
마이크로서비스 통합 예시
Route 53
(api.mycompany.com)
│
API Gateway
│
┌────────────────┼────────────────┐
│ │ │
/users /products /orders
│ │ │
▼ ▼ ▼
Lambda (사용자) ECS (상품) EC2 (주문)
│ │ │
▼ ▼ ▼
DynamoDB RDS RDS장점
| 장점 | 설명 |
|---|---|
| 단일 진입점 | 클라이언트는 하나의 도메인만 알면 됨 |
| 보안 집중화 | 인증/인가를 한 곳에서 처리 |
| 유연성 | 백엔드는 Lambda, ECS, EC2 등 자유롭게 |
| 버전 관리 | /v1, /v2로 API 버전 분리 |
핵심 요약
Integration Types 선택 가이드
| 상황 | 추천 |
|---|---|
| Lambda + 간단한 구조 | AWS_PROXY ⭐ |
| 데이터 변환 필요 | AWS/HTTP |
| 기존 HTTP 서버 앞에 Gateway만 | HTTP_PROXY |
| 테스트/목업 | MOCK |
Security 선택 가이드
| 상황 | 추천 |
|---|---|
| AWS 내부 서비스 | IAM |
| 모바일/웹 사용자 | Cognito |
| 자체 인증 | Lambda Authorizer |
주요 제한 (시험 필수!)
| 항목 | 값 |
|---|---|
| Throttling (Account) | 10,000 RPS |
| 타임아웃 | 최대 29초 |
| 캐시 TTL | 0 ~ 3600초 |