멱등성

박태현·2025년 6월 26일

예약 프로젝트

목록 보기
9/10

멱등성


동일한 연산을 여러 번 수행하더라도 서버의 최종 상태가 처음 한 번 수행했을 때와 동일하게 유지되는 성질을 의미합니다.

멱등성은 서버의 상태가 동일함을 의미하며, 매 요청마다 반환되는 HTTP 응답 코드나 결과 메시지까지 완전히 동일해야 함을 의미하는 것은 아닙니다.

ex ) DELETE 요청 시 첫 번째는 200 OK, 두 번째는 404 Not Found가 반환될 수 있지만, 리소스가 삭제된 서버의 최종 상태는 동일하므로 멱등합니다.

HTTP 메서드의 안전성과 멱등성


HTTP 메서드안전성멱등성설명
GET / HEAD / OPTIONSOO서버의 상태를 변경하지 않고 단순히 조회하므로 안전하며 멱등함
PUTXO리소스를 완전히 대체하므로 여러 번 수행해도 최종 상태는 동일함
DELETEXO리소스를 삭제하므로 여러 번 수행해도 리소스가 삭제된 상태는 동일함
POSTXX호출할 때마다 새로운 리소스를 생성하거나 상태를 변경하므로 비멱등함
PATCHX△ (기본 X)RFC 스펙상 비멱등. 설계 방식(절댓값 지정 vs 상대값 증가)에 따라 멱등할 수도 있음

  • 안전한 메서드 : 서버의 리소스를 전혀 변경하지 않는 읽기 전용 메서드입니다. ( GET, HEAD, OPTIONS )

  • 안전성 vs 멱등성 : 안전한 메서드는 항상 멱등하지만, 멱등한 메서드가 반드시 안전한 것은 아닙니다. PUT과 DELETE는 서버 상태를 변경하므로 안전하지 않지만, 여러 번 호출해도 최종 상태가 같으므로 멱등합니다.

API 관점


분산 시스템이나 네트워크 통신 환경에서는 타임아웃, 네트워크 끊김, 클라이언트의 중복 클릭 등으로 인해 동일한 요청이 여러 번 전송될 수 있습니다.

  • 비멱등한 API ( ex. 결제 POST 요청) : 네트워크 타임아웃 발생 시 클라이언트가 재시도하면 중복 결제가 발생할 위험이 있습니다.

  • 멱등한 API : 동일한 요청이 중복 전송되더라도 실제 비즈니스 로직(결제 처리)은 단 한 번만 실행되고, 이후 요청에는 이전에 처리된 결과를 반환하므로 안심하고 재시도할 수 있습니다.

멱등한 요청인지 알 수 있는 방법


본질적으로 멱등하지 않은 POST나 PATCH 요청을 멱등하게 만들기 위해 표준 요청 헤더인 Idempotency-Key를 활용합니다.

POST /v1/payments HTTP/1.1
Host: api.example.com
Idempotency-Key: 7b9b1e22-261d-44a3-a006-259160a2b53f
Content-Type: application/json

{
  "amount": 10000,
  "currency": "KRW"
}

처리 흐름

  1. 클라이언트 : UUID v4와 같이 충분히 무작위적이고 고유한 값을 Idempotency-Key 헤더에 담아 요청을 전송합니다.

  2. 서버 (키 조회 및 검증) :멱등성 키 저장소( Redis, DB )에서 해당 키를 조회합니다.

    요청 핑거프린트 검증 : 동일한 멱등성 키로 들어왔으나 요청 본문이 이전 요청과 다르면 에러(422)를 반환합니다.

  3. 서버 (처리 분기):

    • [기록 존재 - 처리 완료] : 실제 로직을 실행하지 않고, 저장소에 보관된 이전 응답(Status Code, Body)을 그대로 재사용하여 반환합니다.
    • [기록 존재 - 처리 중] : 동일한 키로 요청이 진행 중인 상태라면 동시성 충돌 에러(409)를 반환합니다.
    • [기록 없음] : 비즈니스 로직을 실행한 후, (멱등키, 요청 핑거프린트, 응답 결과)를 저장소에 저장하고 결과를 반환합니다. (만료시간/TTL 설정 필수)

예제


여러 API에서 일관된 멱등성을 보장하기 위해 인터셉터나 미들웨어 형태로 컴포넌트화하여 재사용하는 것을 권장하며, 다음과 같은 HTTP 상태 코드로 예외를 응답합니다.

에러 코드 (Status)시나리오 및 원인
400 Bad Request멱등성이 필수인 API에 Idempotency-Key 헤더가 누락되었거나, 올바른 UUID 형식이 아닐 때
409 Conflict동일한 멱등성 키로 첫 번째 요청이 현재 처리 중인 상태에서 두 번째 요청이 연달아 들어왔을 때 (동시성 락)
422 Unprocessable Entity기존에 사용했던 멱등성 키를 재사용했으나, 요청 본문(Payload)이나 파라미터가 첫 요청과 다를 때
profile
꾸준하게

0개의 댓글