본문 바로가기
Spring/Spring Study

[Spring] HTTP 메소드 : PUT과 PATCH의 차이

by ♡˖GYURI˖♡ 2024. 7. 4.
728x90
팀 프로젝트를 진행하던 중, 정보를 업데이트할 때 PUT과 PATCH 중 어떤 것을 사용해야 하는지에 대한 토의(?)가 열렸다.
나는 이제껏 PatchMapping을 주로 써왔기에 PATCH가 맞다고 생각했는데, 찾아보니 PATCH를 권장하지 않는다는 이야기가 있어서 깜짝 놀랐다. 알아봤던 내용을 정리해두면 좋을 것 같아 글로 남긴다.

 

 

HTTP 메소드 중 PUT과 PATCH는 리소스의 업데이트를 의미한다.
리소스를 업데이트한다는 점에서 '똑같은 거 아닌가?'라는 생각이 들지만 둘 사이에는 약간의 차이가 있다.

 

PUT : 리소스의 모든 것을 업데이트한다.

PATCH : 리소스의 일부를 업데이트한다.

 

 

예를 들어 아래와 같은 리소스가 있다고 생각해보자.

고객(customer) 1
이름(name) 김철수
나이(age) 20
전화번호(phone_number) 010-0000-0000

 

PUT 메소드를 사용하여 리소스를 업데이트하려면 아래와 같이 요청을 보내야만 한다.

PUT /customer/1
{
    "name" : "김철수",
    "age" : 20,
    "phone_number" : "010-1111-1111"
}
고객(customer) 1
이름(name) 김철수
나이(age) 20
전화번호(phone_number) 010-1111-1111

 

만약 바꾸고 싶은 전화번호만을 담은 PUT 요청을 보낸다면 어떻게 될까?

PUT /customer/1
{
    "phone_number" : "010-1111-1111"
}
고객(customer) 1
이름(name)  
나이(age)  
전화번호(phone_number) 010-1111-1111

 

보내지지 않은 값인 이름과 나이는 null값이 된다.

위에서 '리소스의 모든 것을 업데이트한다.'라는게 바로 이런 뜻이다.

 

만약 요청한 URI에 자원이 존재하지 않는다면, PUT은 어떻게 동작할까?

PUT /customer/2
{
    "name" : "김영희",
    "age" : 20,
    "phone_number" : "010-2222-2222"
}
고객(customer) 2
이름(name) 김영희
나이(age) 20
전화번호(phone_number) 010-2222-2222

 

PUT은 요청한 URI에 자원이 존재하지 않는다면 새로운 자원을 생성하여 저장하게 된다.

 

 

 

이번에는 PATCH 메소드에 대해 알아보자.

고객(customer) 1
이름(name) 김철수
나이(age) 20
전화번호(phone_number) 010-0000-0000

 

바꾸고 싶은 부분만 넣어 PATCH 요청을 보낸다면 어떻게 될까?

PATCH /customer/1
{
    "phone_number" : "010-1111-1111"
}
고객(customer) 1
이름(name) 김철수
나이(age) 20
전화번호(phone_number) 010-1111-1111

 

PUT 메소드와는 달리 PATCH 메소드는 요청에 포함되어 있는 부분만 변경이 가능하다.

 

만약 요청한 URI에 자원이 존재하지 않는다면?

PATCH /customer/2
{
    "name" : "김영희",
    "age" : 20,
    "phone_number" : "010-2222-2222"
}

 

PUT과 달리 PATCH 메소드는 새로운 자원을 생성하지 못하며, 오류를 응답하게 된다.

 

 

개인 프로젝트를 진행할 때 PATCH의 부분만 수정이 가능하다는 특징 때문에 PatchMapping을 사용하였던 것인데, 사실 PATCH는 잘 사용되지 않는 메소드라고 한다. PUT보다 훨씬 편해보이는데 이유가 무엇인지 궁금해졌다.

 

 

멱등성 관점

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메소드가 멱등성을 가졌다고 말한다.

f(f(x)) = f(x) for any value x

 

즉, 서버로 요청을 여러 번 날리는 행위와 한 번 날리는 행위가 같은 결과를 내면 멱등성이 있다고 할 수 있다.

 

PUT은 멱등성을 가지지만, PATCH는 멱등성을 가지지 않는다고 한다. 그런데 위에 작성한 예시들에서 PUT과 PATCH는 모두 멱등성이 있는 것'처럼' 작동하는 문제가 있다.

 

멱등성이 보장되지 않는 PATCH 메소드의 사용 예시를 하나 들어보겠다.

// 기존 리소스
{
    "name" : "김철수",
    "age" : 20,
    "phone_number" : "010-0000-0000"
}
PATCH customer/1
{
    $increase : 'age',
    value : 1
}

 

이 PATCH 요청의 $increase 필드의 값은 증가시키고 싶은 속성을 의미하고, value 필드의 값은 그 속성을 얼마나 증가시킬 것인지를 나타낸다. 이 경우 API가 호출될 때마다 김철수의 나이는 1씩 증가하기 때문에 멱등성이 보장되지 않는다.

 

그동안 PATCH 메소드를 이런 식으로 작성하지는 않았었지만, 스펙상 구현에 제약이 없는 메소드이기 때문에 위와 같은 사용방법이 표준을 어긴 것은 아니라고 한다.

 

 

 

개인적으로 낸 결론은 'PATCH 메소드는 멱등성을 보장하지 않을 가능성이 있기 때문에, 확실하게 멱등성을 보장하는 PUT 메소드를 사용하는 것이 좋다!'이다.

 

 

 

 


 

 

[ RESTful API] PUT과 PATCH의 차이 - 멱동성을 보장하는 PUT, 멱등성을 보장하지 않는 PATCH

PUT 메소드는 반드시 멱등성을 보장하지만 PATCH 메소드는 멱등성을 보장하지 않을 수도 있다. 멱등성이란 멱등성이란 어떤 대상에 같은 연산을 여러번 적용해도 결과가 달라지지 않는 성질이다.

oen-blog.tistory.com

 

 

[ 기술 스터디 ] PUT과 PATCH 차이

PUT과 PATCH 사이. 미묘한 무언가가 있다.

velog.io

 

 

HTTP 메소드 PUT , PATCH 차이 - 삽질중인 개발자

HTTP Method 중에 PUT와 PATCH는 리소스의 업데이트를 의미한다. 리소스를 업데이트 한다는 점에서는 같은 역할을 하는 메소드처럼 보이지만 두개의 요청에는 약간의 차이가 있다. PUT : 리소스의 모든

programmer93.tistory.com