상세 컨텐츠

본문 제목

HTTP 멱등성(Idempotency) 개념 정리

HTTP

by Wanderer Kim 2025. 12. 18. 01:47

본문

728x90

멱등성(Idempotency)이란?

멱등성(Idempotency)은 수학에서 유래된 용어로, 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미합니다.

HTTP 통신에서의 정의는 다음과 같습니다.

"동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 서버의 상태(State)에 미치는 영향이 동일하다."

즉, 멱등성이 보장된 API라면 네트워크 오류 시 안심하고 재시도(Retry)를 할 수 있습니다. 반면, 멱등하지 않다면 중복 처리가 발생하지 않도록 별도의 조치가 필요합니다.

HTTP Method별 멱등성 분석

HTTP 스펙(RFC 7231)에 따르면 각 메서드는 멱등성 여부가 정의되어 있습니다. 이를 표로 정리하면 다음과 같습니다.

Method 멱등성 안전성 역할
GET Yes Yes 리소스 조회
PUT Yes No 리소스 전세 수정
DELETE Yes No 리소스 삭제
POST No No 리소스 생성
PATCH No No 리소스 부분 수

참고 (안전성, Safe): 서버의 상태를 변경하지 않는지(읽기 전용)를 의미합니다. 멱등성과는 다른 개념입니다.

GET (멱등함 O)

서버에서 데이터를 조회하는 메서드입니다.

  • 설명: 게시글 목록을 1번 조회하든, 100번 조회하든 서버에 저장된 데이터가 변경되지 않습니다. 단순히 데이터를 읽어오기만 하므로 결과는 항상 같습니다.
  • 예시:이 요청을 여러 번 보내도 상품 123번의 정보는 변하지 않으며, 서버 상태도 그대로입니다.
    HTTP
    
    GET /products/123

이 요청을 여러 번 보내도 상품 123번의 정보는 변하지 않으며, 서버 상태도 그대로입니다.

PUT (멱등함 O)

리소스를 대체(Replace) 하는 메서드입니다. (없으면 생성, 있으면 덮어쓰기)

  • 설명: id=1인 유저의 이름을 "철수"로 바꾸라는 요청을 보냅니다. 이 요청을 10번 반복해서 보내도, 최종적으로 서버에 남는 상태는 id=1의 이름이 "철수"라는 사실 하나입니다. **최종 상태(End State)**가 항상 동일합니다.
  • 예시:
HTTP

PUT /users/1
{ "name": "Cheolsu", "age": 25 }

첫 번째 요청 후: 이름 "Cheolsu", 나이 25 두 번째 요청 후: 이름 "Cheolsu", 나이 25 (변화 없음)

DELETE (멱등함 O)

리소스를 삭제하는 메서드입니다.

  • 설명: file.jpg를 삭제하라는 요청을 보냅니다. 첫 번째 요청에 파일이 삭제됩니다. 두 번째 요청을 보내면 이미 파일이 없어서 404 Not Found가 뜰 수 있습니다. 하지만, "서버에 그 파일이 없다"는 상태는 변하지 않았습니다.
  • 중요: 멱등성은 응답 코드(Status Code)가 같은지가 아니라, 서버의 상태(State)가 같은지를 봅니다. (첫 요청 200 OK, 두 번째 404 Not Found여도 서버 상태는 '삭제됨'으로 동일하므로 멱등합니다.)
  • 예시:
HTTP

DELETE /posts/50

POST (멱등하지 않음 X)

리소스를 생성하거나 데이터를 처리하는 메서드입니다.

  • 설명: 가장 주의해야 합니다. 게시글 작성 요청을 보냅니다. 만약 네트워크 오류로 응답을 못 받아 다시 보낸다면? 똑같은 게시글이 2개가 생성됩니다. 서버의 상태가 요청 횟수만큼 변하게 됩니다.
  • 예시:
HTTP

POST /orders
{ "item": "pizza", "qty": 1 }

 

  • 1회 전송: 피자 주문 1건 생성 (Order ID: 101)
  • 2회 전송: 피자 주문 1건 추가 생성 (Order ID: 102) -> 중복 결제 발생 위험

POST의 멱등성을 보장하는 방법: Idempotency Key

그렇다면 결제나 주문 같은 중요한 POST 요청은 어떻게 안전하게 처리해야 할까요? 업계 표준(Stripe, Toss Payments 등)으로 사용되는 패턴이 바로 **'Idempotency Key(멱등성 키)'**입니다.

동작 원리

  1. 클라이언트: 요청 헤더에 유니크한 키(UUID 등)를 담아 보냅니다.
    • Idempotency-Key: 123e4567-e89b...
  2. 서버:
    • 이 키로 들어온 요청이 처음이라면? → 정상 처리 후 결과를 저장소(Redis 등)에 저장.
    • 이미 처리된 키라면? → 로직을 수행하지 않고 저장된 결과를 그대로 반환.

서버 구현 로직 (예시)

# Pseudo Code
def process_payment(request):
    key = request.headers.get('Idempotency-Key')
    
    # 1. 캐시(Redis)에서 키 확인
    if cache.exists(key):
        return cache.get(key) # 저장된 이전 응답 반환
    
    # 2. (선택) 동시 요청 방지를 위한 Lock 획득
    
    # 3. 비즈니스 로직 실행
    result = payment_service.charge()
    
    # 4. 결과 캐싱 (TTL 설정 필수)
    cache.set(key, result, ttl=86400)
    
    return result

 

이 방식을 사용하면 클라이언트가 네트워크 오류로 응답을 못 받아 재요청을 보내더라도, 서버는 중복 결제를 막고 안전하게 이전 성공 결과를 돌려줄 수 있습니다.

결론 및 요약

RESTful API를 설계할 때 멱등성은 선택이 아닌 필수 고려 사항입니다.

  1. GET, PUT, DELETE는 멱등하므로 네트워크 에러 시 재시도가 비교적 안전합니다.
  2. POST는 멱등하지 않으므로, 데이터 생성이나 결제 같은 민감한 로직에서는 주의해야 합니다.
  3. Idempotency Key 패턴을 활용하면 POST 요청도 멱등하게 만들 수 있어 시스템의 신뢰성을 크게 높일 수 있습니다.
반응형

'HTTP' 카테고리의 다른 글

SOAP 통신  (0) 2024.04.02
웹 브라우저 요청 흐름  (0) 2022.07.10
URI(Uniform Resource Identifier)  (0) 2022.07.10
DNS(Domain Name System)  (0) 2022.07.08
Port  (0) 2022.07.08

관련글 더보기

댓글 영역