포스트

PUT vs PATCH — 단순한 수정 범위를 넘어 멱등성으로 이해하기

PUT vs PATCH — 단순한 수정 범위를 넘어 멱등성으로 이해하기

배경

PUTPATCH를 구분할 때 흔히 다음처럼 이해한다.

  • PUT → 전체 수정
  • PATCH → 일부 수정

이 기준만으로 회원 정보 수정 API를 설계하다 보니 이런 고민이 생겼다.

  • PUT이면 모든 필드를 다 보내야 하는가?
  • 수정 불가능한 값까지 요청에 포함하는 것은 비효율적인가?

하지만 이 문제는 단순히 “데이터를 얼마나 보내야 하는가”가 아니라 API의 성질과 책임 분리(프론트 vs 서버) 관점에서 봐야 한다.


핵심 기준: 멱등성 (Idempotency)

HTTP Method 선택의 핵심은 멱등성이다.

동일한 요청을 여러 번 보내더라도 결과 상태가 동일해야 하는가?

이 질문을 기준으로 보면 PUT과 PATCH의 역할이 명확해진다.


PUT — 상태를 정의하는 요청

PUT은 리소스를 특정 상태로 만든다는 의미를 가진다.

  • 멱등성 보장
  • 동일 요청 → 동일 결과
  • 선언적 성격 (desired state)

중요한 포인트

많이 오해하는 부분:

PUT = 모든 필드를 반드시 포함해야 한다 ❌

실제로는 다음이 더 중요하다.

“이 요청으로 리소스의 최종 상태가 명확하게 정의되는가?” ✔


프론트 관점에서의 역할

회원 정보 수정 API를 생각해보면:

  • 프론트에서 수정 가능한 필드만 UI에서 노출
  • 수정 불가능한 필드는 애초에 입력 자체를 차단

즉,

👉 프론트가 이미 수정 범위를 제어하고 있음

따라서 서버는 다음만 보장하면 된다.

  • 전달된 필드만 반영
  • 허용되지 않은 필드는 무시 또는 검증 에러 처리

예시

1
2
3
4
5
6
PUT /users/me

{
  "nickname": "wooram",
  "profileImage": "url"
}

이 요청의 의미는 다음과 같다.

“내 회원 정보는 이 상태여야 한다”

  • 여러 번 호출해도 결과 동일 → 멱등성 유지
  • 일부 필드만 포함되었지만 문제 없음

PATCH — 변화를 적용하는 요청

PATCH는 리소스에 대해 변경을 수행하는 행위에 초점이 있다.

  • 멱등성이 보장되지 않을 수 있음
  • 상태가 아니라 “동작”을 표현

비밀번호 변경이 PATCH인 이유

비밀번호 변경은 일반 필드 수정과 성격이 다르다.

  • 매 실행마다 내부적으로 해싱 처리
  • 동일 입력이라도 결과 값(해시)은 달라질 수 있음
  • “상태 정의”보다 “변경 행위”에 가까움

예시

1
2
3
4
5
PATCH /users/me/password

{
  "password": "newPassword123!"
}

이 요청의 의미는 다음과 같다.

“비밀번호를 변경해라”

  • 동일 요청 반복 시 내부 결과 동일 보장 어려움
  • 행위 중심 API

프론트와 서버의 책임 분리

이 부분이 실제 설계에서 중요하다.

프론트

  • 어떤 필드를 수정할 수 있는지 결정
  • 수정 불가능한 필드는 입력 자체를 차단

서버

  • 전달된 데이터의 유효성 검증
  • 허용된 필드만 반영
  • 멱등성 유지 여부 보장

핵심 포인트

“모든 필드를 보내야 하는가?”는 중요한 질문이 아니다.

더 중요한 질문은:

  • 이 요청이 상태를 정의하는가? (PUT)
  • 아니면 변화를 수행하는가? (PATCH)

정리

구분PUTPATCH
기준상태 정의변화 적용
멱등성보장보장되지 않을 수 있음
요청 성격선언적명령형
프론트 역할수정 가능한 필드만 전달특정 행위 트리거
예시회원 정보 수정비밀번호 변경

결론

  • PUT vs PATCH는 단순히 “전체 vs 일부 수정”의 문제가 아니다
  • 멱등성과 요청의 의미가 핵심 판단 기준이다
  • 프론트가 수정 범위를 제어하고 있다면, PUT에서도 일부 필드만 전달하는 것은 자연스러운 설계다

한 줄 정리

PUT은 상태를 정의하고, PATCH는 변화를 실행한다.

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