POST는 멱등한가요? 아니요, PUT과 DELETE는 멱등합니다

아니요, HTTP는 GET, HEAD, OPTIONS, TRACE, PUT, DELETE를 멱등하다고 정의하지만 POST와 PATCH는 아닙니다. 멱등성 키가 있으면 POST 재시도가 안전합니다.

읽는 시간 4분Sume
전체 글

아니요, POST는 멱등하지 않습니다. HTTP 표준인 RFC 9110은 PUT, DELETE, 그리고 안전한 메서드인 GET, HEAD, OPTIONS, TRACE를 멱등한 메서드로 정의합니다. 동일한 요청을 여러 번 보내도 서버에 미치는 의도된 효과가 한 번 보냈을 때와 같다는 뜻입니다. POST는 보낸 내용을 서버가 자체 규칙대로 처리해 달라는 요청이며, 그 처리는 요청할 때마다 새 레코드를 만드는 일일 수 있습니다. PATCH도 정의상 멱등하지 않습니다.

메서드 정의는 RFC 9110, RFC 5789, 그리고 MDN 용어집의 멱등(Idempotent)과 안전(Safe) 항목에서 인용했습니다. Sume의 재시도 동작은 Format 호출하기 (영문), Job과 결과 (영문), 실행 기다리기 (영문) 문서와 현재 SDK 코드에서 가져왔습니다. 모두 2026-09-28에 확인했습니다.

어떤 HTTP 메서드가 멱등한가요?

RFC 9110은 자신이 정의하는 메서드마다 안전한지, 멱등한지를 표시합니다. PATCH는 RFC 5789에서 정의하며, 이 RFC는 PATCH가 둘 다 아니라고 말합니다.

멱등성은 응답이 아니라 서버에 미치는 의도된 효과를 가리킵니다. MDN의 예시에서 레코드를 처음 DELETE하면 대개 200이 돌아오고 반복하면 404가 돌아오지만, 어느 쪽이든 레코드는 사라집니다. 그래도 서버는 요청을 하나하나 로그로 남길 수 있습니다. RFC 9110은 이 속성이 클라이언트가 요청한 것에만 적용된다고 말합니다.

RFC 9110 18.2절, PATCH는 RFC 5789 기준, 2026-09-28 확인.
메서드안전멱등
GET예예
HEAD예예
OPTIONS예예
TRACE예예
PUT아니요예
DELETE아니요예
POST아니요아니요
PATCH아니요아니요
CONNECT아니요아니요

안전한 메서드와 멱등한 메서드는 무엇이 다른가요?

안전한 메서드는 정의상 읽기 전용입니다. 클라이언트는 서버의 상태 변경을 요청하지도, 기대하지도 않습니다. 멱등한 메서드는 상태를 바꿀 수 있지만, 반복해도 그 이상은 바뀌지 않습니다. 따라서 안전한 메서드는 모두 멱등하지만, 멱등한 메서드가 모두 안전한 것은 아닙니다. MDN이 드는 예는 멱등하지만 안전하지 않은 PUT과 DELETE입니다.

이 두 속성 덕분에 소프트웨어가 알아서 동작할 수 있습니다. 크롤러와 프리페칭은 해를 끼칠 걱정 없이 안전한 요청을 보낼 수 있고, 클라이언트는 응답을 읽기 전에 연결이 끊기면 멱등한 요청을 자동으로 반복할 수 있습니다.

PUT은 멱등한데 POST는 왜 멱등하지 않나요?

본문이 뜻하는 바가 다르기 때문입니다. PUT은 대상 리소스를 본문에 담긴 상태로 만들거나 바꿔 달라는 요청이므로, 같은 본문을 두 번 보내도 상태는 같습니다. POST는 대상 리소스가 자체 규칙대로 본문을 처리해 달라는 요청입니다. 예를 들어 서버가 아직 이름을 붙이지 않은 새 리소스를 만들거나 데이터를 덧붙이는 식입니다. RFC 9110은 PUT의 의도가 멱등하다는 점을 두 메서드의 근본적인 차이로 꼽습니다. MDN의 반례는 호출할 때마다 행을 하나씩 더 추가하는 POST /add_row입니다.

API가 무언가를 만들 때 POST를 쓰는 이유도 여기에 있습니다. RFC 9110은 새 리소스의 URI를 서비스가 직접 정한다면 PUT 대신 POST를 써야 한다고 말합니다.

PATCH는 멱등한가요?

정의상으로는 멱등하지 않습니다. RFC 5789는 PATCH가 안전하지도 멱등하지도 않다고 말합니다. 본문은 리소스를 바꾸는 명령의 집합이고, 이를 적용하면 다른 리소스가 만들어지거나 바뀔 수도 있습니다. 필드를 고정된 값으로 설정하는 패치는 반복해도 문제가 없지만, 목록에 항목을 덧붙이거나 카운터 값을 더하는 패치는 그렇지 않습니다. 이 RFC는 PATCH를 멱등하게 보낼 수도 있다고 언급하며, 패치 형식이 알려진 시작 버전을 전제로 한다면 If-Match ETag 같은 조건부 요청을 보내 오래된 패치가 실패하게 하라고 클라이언트에 안내합니다.

POST는 어떻게 안전하게 재시도하나요?

서버가 반복 요청을 알아볼 수단을 주세요. RFC 9110은 요청이 실제로 멱등하다는 것이나 원래 요청이 적용되지 않았다는 것을 알 수단이 없다면, 클라이언트가 멱등하지 않은 요청을 자동으로 재시도해서는 안 된다고 말합니다. 멱등성 키가 바로 그 수단입니다. 클라이언트는 POST에 고유한 키를 함께 보내고, 서버는 같은 키와 본문으로 반복된 요청에 작업을 다시 하는 대신 첫 결과로 응답합니다.

Sume에서는 생성 요청의 Idempotency-Key 헤더가 그 키입니다. 같은 키와 같은 본문을 보내면 두 번째 실행도, 두 번째 청구도 없이 원래 영수증과 함께 200이 돌아옵니다. 키를 만드는 방법과 재전송했을 때 나오는 모든 결과는 AI 영상 API 멱등성 키에서 다룹니다.

Sume의 TypeScript SDK는 이 RFC 규칙을 따릅니다. 현재 코드에서 SDK는 408, 429, 5xx나 전송 실패 뒤에 GET이나 HEAD는 재시도하지만, POST는 Idempotency-Key가 있을 때만 재시도합니다. 키 없이 다시 보내면 두 번째 실행이 시작되고 청구되기 때문입니다.

POST를 설계 단계에서 멱등하게 만들 수도 있습니다. Sume에서 이미 canceled 상태인 Job에 POST /v1/jobs/{id}/cancel을 보내면 같은 취소된 Job이 돌아옵니다. Sume API로 AI 영상 생성 Job이나 실행을 취소하는 방법에서 설명하는 내용입니다.

출처

관련 글

개발자 카테고리의 다른 글

개발자 글 전체 보기

작성자 Sume