PUT vs PATCH — 단순한 수정 범위를 넘어 멱등성으로 이해하기
PUT vs PATCH — 단순한 수정 범위를 넘어 멱등성으로 이해하기
배경
PUT과 PATCH를 구분할 때 흔히 다음처럼 이해한다.
- 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)
정리
| 구분 | PUT | PATCH |
|---|---|---|
| 기준 | 상태 정의 | 변화 적용 |
| 멱등성 | 보장 | 보장되지 않을 수 있음 |
| 요청 성격 | 선언적 | 명령형 |
| 프론트 역할 | 수정 가능한 필드만 전달 | 특정 행위 트리거 |
| 예시 | 회원 정보 수정 | 비밀번호 변경 |
결론
- PUT vs PATCH는 단순히 “전체 vs 일부 수정”의 문제가 아니다
- 멱등성과 요청의 의미가 핵심 판단 기준이다
- 프론트가 수정 범위를 제어하고 있다면, PUT에서도 일부 필드만 전달하는 것은 자연스러운 설계다
한 줄 정리
PUT은 상태를 정의하고, PATCH는 변화를 실행한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.