Pink Spider/멱등성(Idempotence)에 대하여

Created Mon, 26 May 2025 20:20:45 +0900 Modified Mon, 08 Dec 2025 08:41:47 +0900
1734 Words 8 min

멱등성(Idempotence)은 컴퓨터 과학에서 자주 등장하는 중요한 개념입니다. 아래에 일반적인 의미와 API 개발과의 관련성을 나누어 자세히 설명드리겠습니다.


💡 멱등성(Idempotence)이란?

멱등성이란 동일한 연산을 여러 번 수행해도 결과가 같아지는 성질을 말합니다. 수학에서 출발한 개념인데, 예를 들어 함수 f(x)가 있을 때 다음이 성립하면 멱등함수라고 합니다:

f(f(x)) = f(x)

예시 (수학적 관점)

  • 절댓값 함수: | |x|| = |x|
  • 집합의 합집합 연산: A ∪ A = A

🌐 멱등성과 API 개발

웹 API 설계 시, 멱등성은 안정적이고 예측 가능한 API를 만들기 위해 매우 중요한 성질입니다. 특히 REST API에서는 각 HTTP 메서드가 멱등성을 가질지를 설계 시 명확히 고려해야 합니다.

HTTP 메서드와 멱등성

HTTP 메서드 멱등성 여부 설명
GET ✅ 멱등성 O 같은 자원을 조회하기 때문에 여러 번 요청해도 결과는 동일
PUT ✅ 멱등성 O 자원을 “덮어쓰기” 하기 때문에 같은 데이터로 요청하면 항상 동일한 상태 유지
DELETE ✅ 멱등성 O 이미 삭제된 자원을 다시 삭제 요청해도 에러는 없고, 상태는 동일
POST ❌ 멱등성 X 새로운 자원을 생성하므로 여러 번 호출하면 중복 생성될 수 있음
PATCH ❌ (보통은) 일부만 수정하므로, 같은 요청 반복 시 결과가 달라질 수 있음

🎯 예시를 통한 이해

✅ 멱등한 API 예제 (PUT)

PUT /users/123
Body: {
  "name": "Alice",
  "email": "alice@example.com"
}
  • 같은 요청을 여러 번 보내도 사용자 123의 정보는 항상 위 내용으로 덮어쓰기 되므로 멱등성 O

❌ 멱등하지 않은 API 예제 (POST)

POST /orders
Body: {
  "item": "book",
  "quantity": 1
}
  • 같은 요청을 여러 번 보내면 주문이 여러 개 생성될 수 있음 → 멱등성 X

🛡️ 왜 멱등성이 중요한가?

  1. 재시도 로직에서 안전성 확보

    • 네트워크 오류, 타임아웃으로 인한 재요청 시 멱등성이 보장되면 중복 요청으로 인한 문제를 방지할 수 있음.
  2. 클라이언트-서버 간 신뢰성 강화

    • 어떤 요청을 여러 번 보냈을 때 항상 같은 결과라면 시스템의 신뢰성과 유지보수성이 향상됨.
  3. Load Balancer / Proxy / Retry System에서 유리

    • 중간 장비나 클라이언트가 자동 재시도를 수행할 때도, 멱등성 여부에 따라 부작용 여부가 결정됨.

📌 정리

  • 멱등성은 “동일한 연산을 여러 번 수행해도 결과가 같다"는 개념.
  • API 설계 시에는 HTTP 메서드의 특성과 멱등성 여부를 고려해야 함.
  • 재시도 가능한 안정적인 API 설계에 있어 멱등성은 핵심 고려 요소 중 하나임.

좋습니다! 멱등성을 고려한 API 설계 패턴과 재시도-safe한 시스템 구현 예제를 구체적으로 정리해드리겠습니다.


🧱 1. 멱등성을 고려한 API 설계 패턴

✅ 패턴 1: PUT 사용으로 자원 전체 덮어쓰기

  • 설명: 동일한 요청을 여러 번 보내도 항상 자원이 같은 상태로 유지됨.

  • 예제:

    PUT /users/123
    {
      "name": "Alice",
      "email": "alice@example.com"
    }
    
    • 여러 번 호출해도 항상 동일한 상태 유지.

✅ 패턴 2: 클라이언트에서 idempotency key 사용

  • 설명: 중복 요청을 방지하기 위해 요청에 고유 식별자(예: UUID)를 함께 전송.

  • 주로 사용하는 메서드: POST (비멱등 메서드에 멱등성을 부여)

  • 헤더 예시:

    POST /payments
    Idempotency-Key: 123e4567-e89b-12d3-a456-426614174000
    Body: {
      "amount": 1000,
      "card": "**** **** **** 1234"
    }
    
  • 서버 동작 방식:

    • 서버는 Idempotency-Key를 기준으로 요청 결과를 캐싱하거나 DB에 저장.
    • 같은 키로 요청이 오면 이전 응답을 그대로 반환 → 중복 처리 방지.

✅ 패턴 3: 서버 측 상태 저장 (Request Tracking Table)

  • 설명: 처리된 요청을 기록하고, 동일 요청이 다시 들어오면 이전 응답을 반환하거나 무시.

  • 예시: 주문, 결제, 송금 등에서 중복 요청 방지.

  • 구현 방식:

    • 요청마다 고유 트랜잭션 ID (예: transactionId) 포함.
    • DB에 트랜잭션 ID 저장 후 중복 여부 검사.

⚙️ 2. 재시도-safe한 시스템 구현 예제

💳 예제: 결제 처리 API (POST /payments)

클라이언트 측 요청

POST /payments
Headers:
  Idempotency-Key: d9f3e1ae-45b4-4f2f-b8d1-63e67256b9ea

Body:
{
  "userId": 123,
  "amount": 5000
}

서버 측 처리 로직 (Java/Spring 기준 의사코드)

public ResponseEntity<?> createPayment(String idempotencyKey, PaymentRequest request) {
    Optional<PaymentLog> existing = paymentRepository.findByIdempotencyKey(idempotencyKey);

    if (existing.isPresent()) {
        return ResponseEntity.ok(existing.get().getResponse());
    }

    PaymentResult result = paymentService.charge(request);

    PaymentLog log = new PaymentLog(idempotencyKey, result);
    paymentRepository.save(log);

    return ResponseEntity.ok(result);
}

결과:

  • 같은 결제 요청을 재시도해도 중복 결제 없이 이전 결제 결과를 그대로 반환함.
  • 결제 시스템, 주문 시스템, 계좌 이체 등에서 유용하게 사용됨.

📦 추가 설계 팁

🔁 재시도 가능 로직과 함께 사용할 수 있는 전략

  • 재시도 지연(backoff): 네트워크 실패 등에서 지수적으로 요청 간 간격 증가.
  • Retry-After 헤더: 서버가 일정 시간 이후 재시도를 유도.
  • Circuit Breaker 패턴: 실패율이 높은 경우 일시적으로 요청을 차단.

🛑 재시도 시 주의사항

상황 주의
재고 감소, 포인트 차감 등 가변 상태 멱등성 미보장 시 중복 차감 위험
외부 시스템 호출 외부 시스템이 멱등성을 제공하는지 확인 필수
DB 트랜잭션 처리 트랜잭션 ID를 활용한 안전한 중복 방지 로직 필요

✅ 정리

  • 멱등성은 요청 재시도와 장애 대응에서 핵심.
  • PUT, DELETE는 기본적으로 멱등, POSTIdempotency-Key 등으로 보완.
  • 서버에서 요청 추적, 응답 캐싱, DB 중복 검사 등을 통해 시스템적으로 멱등성을 구현할 수 있음.