Django에서 Idempotent Delete 구현하기
Source: Dev.to

오늘 나는 Django 재고 시스템의 삭제 뮤테이션을 작업했다. 목표는 엔드포인트를 멱등하게 만드는 것이었다:
DELETE /items/<item_id>/
- 아이템이 존재하면 → 삭제
- 존재하지 않으면 → 아무 변화 없음
- 언제든지 재시도해도 안전
The bug
삭제가 실제로 상태를 변경하지 않았다.
나는 다음과 같이 호출하고 있었다:
Item.objects.filter(item_id).delete()
대신에:
Item.objects.filter(id=item_id).delete()
을 사용해야 했다.
쿼리가 올바른 필드로 필터링되지 않았기 때문에 상태 전이가 일어나지 않았다. 엔드포인트는 동작하는 것처럼 보였지만, 실제로는 기본 상태가 올바르게 수정되지 않았다.
The fix
다음과 같이 사용한다:
Item.objects.filter(id=item_id).delete()
그리고 트랜잭션 안에서 실행하면 삭제가 자연스럽게 멱등하게 된다:
- 존재하는 아이템 → 삭제됨
- 없는 아이템 → 아무 작업도 하지 않음
- 재시도 시에도 안전
추가적인 조건문 로직이 필요하지 않다.
System takeaway
멱등성은 더 많은 제어 흐름을 추가하기보다 쿼리와 상태 전이 방식을 어떻게 설계하느냐에 달려 있다.
이와 같이 삭제를 설계하면 서비스는:
- 무상태(stateless)
- 재시도 안전(retry‑safe)
- 예측 가능(predictable)
Next step
다음 기능은 원자성 있는 수량 업데이트이다:
- 불변 조건(invariant) 적용
- 트랜잭션 경계 설정
- 손실 업데이트 방지
하루에 하나씩 기능을 구현하고, 먼저 정확성에 집중한다.