포스트

멱등성(Idempotency), 재시도해도 안전한 API 만들기

같은 요청을 여러 번 보내도 결과가 한 번 보낸 것과 똑같이 유지되는 성질을 멱등성(idempotency)이라고 한다. 말로만 들으면 당연한 얘기 같은데, 막상 네트워크가 불안정한 환경에서 API를 설계하다 보면 은근히 신경 써야 하는 부분이다. 클라이언트가 응답을 못 받아서 같은 요청을 재시도했는데, 사실 서버는 이미 그 요청을 처리해놓은 상태라면 어떻게 될까? 멱등성이 보장되지 않은 API라면 여기서 문제가 생긴다.

HTTP 스펙만 봐도 메서드별로 멱등해야 하는지 아닌지가 이미 정해져 있다. GET, PUT, DELETE는 몇 번을 호출해도 서버 상태가 한 번 호출한 것과 같아야 하는 멱등 메서드다. 반면 POST는 호출할 때마다 새 리소스가 만들어지는 식으로 상태가 계속 쌓일 수 있어서 멱등하지 않다고 본다. 그래서 같은 결제 요청을 POST로 두 번 보내면 결제가 두 번 일어날 수도 있는 거고, 반대로 DELETE는 같은 리소스를 몇 번을 지우려 해도 결과는 “그 리소스가 없다”는 동일한 상태로 수렴해야 한다.

이 특성이 진짜 중요해지는 건 분산 시스템에서다. 네트워크 타임아웃이나 일시적인 장애 때문에 클라이언트가 같은 요청을 재시도하는 일이 실제로 꽤 자주 일어난다. 이때 서버가 재시도된 요청을 매번 새로운 요청으로 취급해서 중복 처리해버리면 곤란하다. 그래서 실무에서는 멱등키 (idempotency key)라는 개념을 쓴다. 클라이언트가 요청을 보낼 때마다 고유한 키를 함께 붙이고, 서버는 이미 처리한 멱등키를 어딘가에 기록해둔다. 같은 키로 요청이 다시 들어오면 서버는 새로 처리하지 않고 처음 처리했을 때의 결과를 그대로 돌려준다. 이렇게 하면 원래는 멱등하지 않은 POST 같은 요청도 안전하게 재시도할 수 있게 된다.

결국 멱등성은 “재시도해도 괜찮은 API”를 만들기 위한 가장 기본적인 설계 원칙인 셈이다. API를 새로 설계할 때마다 이 요청을 재시도해도 안전한지 한 번쯤 생각해보는 습관을 들이면 좋을 것 같다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

인기 태그