반응형
들어가며
REST API를 설계할 때 고려해야 할 중요한 개념 중 하나가 바로 멱등성(Idempotency)입니다. 멱등성은 동일한 요청을 여러 번 보내도 서버의 상태가 동일하게 유지되는 성질을 말합니다. 이번 글에서는 HTTP 메서드의 멱등성에 대해 자세히 알아보고, 실제 사용 사례와 함께 살펴보겠습니다.
1. 멱등성이란?
정의
멱등성은 수학에서 유래한 개념으로, 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미합니다. HTTP 메서드의 맥락에서는, 동일한 요청을 한 번 보내는 것과 여러 번 보내는 것이 서버에 동일한 효과를 가져오는 경우를 멱등하다고 합니다.
멱등한 HTTP 메서드
- GET
- HEAD
- PUT
- DELETE
- TRACE
- OPTIONS
멱등하지 않은 HTTP 메서드
- POST
- PATCH
2. 각 HTTP 메서드의 멱등성 분석
GET
GET /api/users/1
- 여러 번 요청해도 동일한 사용자 정보를 반환
- 서버 상태를 변경하지 않음
- 완벽한 멱등성 보장
PUT
PUT /api/users/1
{
"name": "John Doe",
"email": "john@example.com"
}
- 동일한 요청을 여러 번 보내도 최종 상태는 동일
- 리소스를 완전히 대체하는 작업
- 멱등성 보장
DELETE
DELETE /api/users/1
- 첫 번째 요청으로 리소스 삭제
- 이후 요청은 이미 삭제된 상태 유지
- 멱등성 보장
POST
POST /api/orders
{
"productId": 123,
"quantity": 1
}
- 매 요청마다 새로운 주문 생성
- 서버 상태가 요청마다 변경
- 멱등하지 않음
3. 멱등성의 실제 활용
1. 네트워크 오류 처리
async function createOrder(orderData) {
try {
const response = await fetch('/api/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
return response.json();
} catch (error) {
// 네트워크 오류 발생 시 재시도
return retryRequest('/api/orders', orderData);
}
}
2. 멱등성 키 활용
async function createPayment(paymentData) {
const idempotencyKey = generateUniqueKey();
const response = await fetch('/api/payments', {
method: 'POST',
headers: {
'Idempotency-Key': idempotencyKey
},
body: JSON.stringify(paymentData)
});
return response.json();
}
3. 서버 측 구현 예시
from flask import Flask, request
import redis
app = Flask(__name__)
redis_client = redis.Redis()
@app.route('/api/payments', methods=['POST'])
def create_payment():
idempotency_key = request.headers.get('Idempotency-Key')
if idempotency_key:
# 이전 요청 결과 확인
cached_response = redis_client.get(idempotency_key)
if cached_response:
return cached_response
# 결제 처리 로직
payment_result = process_payment(request.json)
# 결과 캐싱
if idempotency_key:
redis_client.setex(idempotency_key, 3600, payment_result)
return payment_result
4. 멱등성 설계 모범 사례
1. 멱등성 키 사용
- 고유한 요청 식별자 생성
- 서버에서 중복 요청 감지
- 일정 시간 동안 결과 캐싱
2. 상태 확인 메커니즘
async function safePayment(paymentData) {
// 1. 결제 상태 확인
const status = await checkPaymentStatus(paymentData.orderId);
if (status === 'COMPLETED') {
return { status: 'success', message: '이미 처리된 결제입니다.' };
}
// 2. 결제 처리
return processPayment(paymentData);
}
3. 에러 처리
async function handlePaymentError(error, paymentData) {
if (error.type === 'NETWORK_ERROR') {
// 멱등한 요청인 경우 재시도
if (isIdempotentRequest(paymentData)) {
return retryPayment(paymentData);
}
// 멱등하지 않은 요청은 상태 확인 후 처리
return verifyAndProcessPayment(paymentData);
}
throw error;
}
5. 주의사항
1. 멱등성의 한계
- 서버 시간에 따른 상태 변화
- 외부 시스템과의 연동
- 동시성 문제
2. 구현 시 고려사항
- 적절한 타임아웃 설정
- 재시도 횟수 제한
- 로깅과 모니터링
결론
멱등성은 안정적인 API 설계의 핵심 요소입니다. 특히 결제, 주문 처리와 같은 중요한 비즈니스 로직에서 멱등성을 보장하는 것은 시스템의 신뢰성과 안정성을 높이는 데 큰 도움이 됩니다. 개발자는 각 HTTP 메서드의 특성을 이해하고, 상황에 맞는 적절한 설계를 통해 멱등성을 보장해야 합니다.
참고 자료
반응형
'Backend Development' 카테고리의 다른 글
MySQL Replication 완벽 가이드: 고가용성과 데이터 안정성 확보 (2) | 2025.05.29 |
---|---|
Java Record 완벽 가이드: DTO와 VO 구현의 새로운 패러다임 (6) | 2025.05.29 |
프록시 서버의 두 가지 유형: 포워드 프록시와 리버스 프록시 (0) | 2025.05.29 |
HTTPS: 웹 보안의 기본, 안전한 통신의 시작 (2) | 2025.05.29 |
스택(Stack) 자료구조: 개념부터 구현까지 (4) | 2025.05.29 |