REST API 설계 | RESTful 원칙부터 보안까지
REST API란?
REST (Representational State Transfer)는 웹 기반 API 설계 아키텍처입니다.
특징:
- 리소스 기반 (users, posts, comments)
- HTTP 메소드 활용 (GET, POST, PUT, DELETE)
- 상태 비저장 (stateless)
- 캐시 가능
기본 규칙: CRUD
CREATE (생성) → POST /users
POST /posts
READ (읽기) → GET /users
GET /users/1
GET /posts
UPDATE (수정) → PUT /users/1
PATCH /posts/1
DELETE (삭제) → DELETE /users/1
DELETE /posts/1RESTful API 설계 원칙
1. 리소스 지향 (Resource-Oriented)
❌ 나쁜 설계
GET /getUser?id=1
GET /createPost
DELETE /removeComment?id=5
✅ 좋은 설계
GET /users/1
POST /posts
DELETE /comments/52. HTTP 메소드 올바른 사용
GET: 안전 (데이터 변경 없음), 멱등성 있음 (반복해도 같음)
POST: 새 리소스 생성 (멱등성 없음)
PUT: 리소스 전체 교체 (멱등성 있음)
PATCH: 리소스 일부 수정 (멱등성 없음)
DELETE: 리소스 삭제 (멱등성 있음)3. 상태 코드 올바른 사용
200 OK: 요청 성공
201 Created: 리소스 생성 성공 (POST 응답)
204 No Content: 성공하지만 반환값 없음 (DELETE)
400 Bad Request: 잘못된 요청
401 Unauthorized: 인증 실패
403 Forbidden: 권한 없음
404 Not Found: 리소스 없음
500 Server Error: 서버 오류예시:
POST /users
응답: 201 Created
{ "id": 1, "name": "John" }
GET /users/999
응답: 404 Not Found
{ "error": "User not found" }4. 명사 사용 (동사 금지)
❌ 나쁜 예
/getUsers
/createPost
/deleteComment
✅ 좋은 예
/users (GET으로 조회)
/posts (POST로 생성)
/comments/5 (DELETE로 삭제)API 버전 관리
URL 경로에 버전 포함 (권장)
/api/v1/users
/api/v2/users
/api/v3/users장점:
- 명확한 버전 구분
- URL에서 직접 확인 가능
헤더에 버전 포함
GET /users
Accept: application/vnd.api+json;version=1
또는
X-API-Version: 1쿼리 파라미터
GET /users?api_version=1인증 (Authentication)
JWT (JSON Web Token) - 가장 인기
// 로그인
POST /auth/login
{ "email": "user@example.com", "password": "123456" }
응답:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}
// API 사용
GET /users
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...구조:
Header.Payload.Signature
Header: { "alg": "HS256", "typ": "JWT" }
Payload: { "userId": 1, "exp": 1234567890 }
Signature: hmacSHA256(base64(header) + "." + base64(payload), secret)OAuth 2.0 (소셜 로그인)
사용자가 "Google로 로그인" 클릭
↓
구글 로그인 페이지로 리다이렉트
↓
구글 인증 후 authorization code 받기
↓
우리 앱이 authorization code로 토큰 요청
↓
access token 획득
↓
API 호출사용 시기: SNS 연동, 소셜 로그인
에러 처리
일관된 에러 응답 포맷
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is invalid",
"details": [
{
"field": "email",
"issue": "Must be a valid email address"
}
]
}
}에러 코드 정의
VALIDATION_ERROR (400): 입력값 오류
UNAUTHORIZED (401): 인증 실패
FORBIDDEN (403): 권한 없음
NOT_FOUND (404): 리소스 없음
CONFLICT (409): 충돌 (예: 중복 이메일)
INTERNAL_ERROR (500): 서버 오류페이지네이션
쿼리 파라미터 방식
GET /posts?page=2&limit=10
응답:
{
"data": [...],
"pagination": {
"page": 2,
"limit": 10,
"total": 100,
"pages": 10
}
}Cursor 방식 (성능 최고)
GET /posts?limit=10&cursor=abc123
응답:
{
"data": [...],
"pagination": {
"next_cursor": "xyz789",
"has_more": true
}
}Offset vs Cursor:
- Offset: 간단하지만 느림 (많은 행 스킵)
- Cursor: 복잡하지만 빠름 (실시간 데이터 최적)
레이트 제한 (Rate Limiting)
X-RateLimit-Limit: 1000 (시간당 최대 요청)
X-RateLimit-Remaining: 850 (남은 요청)
X-RateLimit-Reset: 1234567890 (초기화 시간)정책:
- 일반 사용자: 시간당 1,000 요청
- 유료 사용자: 시간당 10,000 요청
- 초과 시: 429 Too Many Requests
CORS (Cross-Origin Resource Sharing)
프론트엔드: http://localhost:3000
백엔드 API: http://api.example.com
↓
브라우저가 차단 (다른 도메인)
↓
백엔드에서 CORS 허용 설정:
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, AuthorizationAPI 문서화 (OpenAPI/Swagger)
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: 모든 사용자 조회
parameters:
- name: page
in: query
type: integer
responses:
200:
description: 성공
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'도구:
- Swagger UI: 자동으로 API 문서 생성
- Postman: API 테스트 및 문서화
캐싱
// 응답에 캐시 정보 포함
Cache-Control: public, max-age=3600 // 1시간 캐시
GET /posts
↓
처음 요청: 데이터베이스에서 가져오기
다시 요청: 캐시에서 즉시 반환 (1시간 내)
→ 데이터베이스 부하 30-50% 감소보안 체크리스트
✓ HTTPS 필수 (HTTP 금지)
✓ 입력값 검증 (SQL 인젝션 방지)
✓ 출력 인코딩 (XSS 방지)
✓ 인증 및 권한 확인
✓ 레이트 제한 설정
✓ CORS 올바르게 설정
✓ 민감한 정보 노출 금지
✓ 로그 기록 (감사 추적)
✓ 정기 보안 감사자주 묻는 질문
REST API와 GraphQL의 차이는?
A.
- REST: 고정된 응답 (간단함, 높은 캐시율)
- GraphQL: 필요한 데이터만 요청 (유연함, 복잡함)
HTTP 상태 코드는 몇 개나 써야 하나요?
A. 최소 5개 (200, 201, 400, 404, 500) 충분. 더 많으면 클라이언트가 혼동.
API를 개인이 만들어도 되나요?
A. 당신의 데이터라면 자유. 다른 사람의 API를 이용할 때는 약관 확인.
API는 몇 개 버전을 동시에 지원해야 하나요?
A. 보통 2개 (현재 + 이전 버전). 지원 기간을 명시하세요.
모바일 앱은 API 클라이언트 라이브러리를 써야 하나요?
A. 권장합니다 (Retrofit, Alamofire 등). HTTP 라이브러리보다 편함.
결론
좋은 API 설계는:
RESTful 원칙 준수
↓
명확한 에러 처리
↓
보안 최우선
↓
좋은 문서화
↓
지속적인 개선가장 중요한 것: API 사용자의 입장에서 생각하기. 개발자 경험(DX)이 모든 것.