지난 글에서 HTTP와 HTTPS, 또 이에 대한 메서드들을 공부했다. 여기서 메서드에 대해 공부하던 중 PUT과 PATCH에 대해 더 자세히 알아볼 필요가 있다고 생각했다. PATCH의 어떤 특징때문에 PUT과 구분되어서 써야하는지, 왜 PATCH를 지원하지 않는 서버가 많은지 PUT과의 차이점에 초점을 맞춰 조사했다.
그전에 HTTP메서드에 대해 정리해보자.
위의 표들을 보면 이전 시간에 공부했던 메서드들이 기억난다. PUT은 전체 덮어쓰기 혹은 새로 만들기, PATCH는 부분 덮어쓰기. 이것을 실제 예시로 살펴보고자 한다.
예시 리소스
- /members 내부에 아래와 같은 리소스가 있다고 한다.
ID Name Value 1 JEKKY 100 2 Kim 200 3 Lee 300
여기에 ID가 1번의 value를 500으로 수정하는 경우를 본다면
- 원하는 리소스의 모든 사항을 적을 때
PUT /members?ID=1 { name: JEKKY, Value: 500, }
수정 후 리소스
ID Name Value 1 JEKKY 500 2 Kim 200 3 Lee 300
- 수정하고자 하는 리소스만 적을 때
PUT /members?ID=1 { Value: 500, }
수정 후 리소스
ID Name Value 1 500 2 Kim 200 3 Lee 300
PUT을 이용한다고 하면 이렇게 될 것이다. PUT은 수정해야 하는 위치의 리소스를 body에 담겨있는 내용으로 대체 하는 것이기 때문에 해당 리소스의 요소에 대한 값이 없다면 없는 부분의 데이터는 표와 같이 공백으로 처리가 된다.
2. PATCH의 경우
예시는 PUT과 동일한 것을 쓴다고 할 때
- 원하는 리소스의 모든 사항을 적을 때
PATCH /members?ID=1 { name: JEKKY, Value: 500, }
수정 후 리소스
ID Name Value 1 JEKKY 500 2 Kim 200 3 Lee 300
- 수정하고자 하는 리소스만 적을 때
PATCH /members?ID=1 { Value: 500, }
수정 후 리소스
ID Name Value 1 JEKKY 500 2 Kim 200 3 Lee 300
PATCH는 이와 같이 부분 덮어쓰기를 하기 때문에 위의 예시에선 어떤 방식으로 보내든 수정하고자 하는 리소스를 명시했기 때문에 기존의 데이터를 유지하면서 수정할 수 있게 된다.
위의 예시를 보면 PUT과 PATCH는 같은 Body를 가지고도 다른 결과를 출력한다. 이는 곧 상황에 따라 다르게 써야 한다는 것을 의미한다.
크게 나누자면 위의 두가지 경우를 생각해 나눌 수 있다. 그러나 아래와 같이 일부 정보만 수정하게 될 때에는 주의해야 하는 점인 멱등성 에 대한 문제가 있다.
앞서 든 예시에서는 PUT이든 PATCH든 몇번을 시행하든 같은 결과를 보여주는 것 처럼 보인다. 하지만 만약 PATCH에 값을 지정한 파라미터만큼 증가시키는 함수가 있다고 한다면 어떻게 될까?
변수의 값을 num의 값 만큼 증가 하는 함수 increase가 있다고 하면
PATCH /members?ID=1 { $increase: 'Value', num = 1, }
수정 후 리소스
ID Name Value 1 JEKKY 501 2 Kim 200 3 Lee 300
만약 위의 메시지를 반복해서 보내게 된다면 ID가 1인 리소스의 값은 계속해서 1씩 증가하게 되어 실행마다 리소스가 변하게 될 것이다. 이는 같은 메시지를 반복적으로 실행할 때 결과값이 동일해야 하는 멱등성에 대한 위반이 발생한다.
이러한 부분 때문에 PATCH는 멱등성이 없다고 하는 것이다.
만약 위의 함수가 반복적으로 실행이 필요한 경우가 있다고 한다면 중간에 한번이라도 메시지가 누락된다면 원치 않는 값을 나타낼 수 있으니 PATCH의 사용에 유의해야 하고 일부 서버에서 지원하지 않게 되는 것이다.
하지만 결국 메서드라는 것은 사용자가 원하는 명령을 서버로 전달하기 위한 목표를 가지고 만들어졌다. 이는 곧 메서드라는 것은 의도를 전달할 뿐 실질적인 동작을 나타내는 것이 아니라는 것을 의미한다.
PUT과 PATCH도 많은 사람들이 명령의 종류에 따라 이름을 통일성있게 붙이자고 한 약속(HTTP)에 따른 것이기에 서버에서 이를 어떻게 구현하는가에 따라 위의 설명들이 맞을 수도 있고 틀릴 수도 있다.
이번 글에서는 PUT과 PATCH의 차이점에 집중해서 글을 적었다. PUT은 리소스를 완전대체하거나 새로 생성하는 전체 덮어쓰기의 역할, PATCH는 리소스의 일부 자원만 변경하는 부분 변경의 역할을 한다. 이때 PUT은 리소스들의 내용을 모두 작성하여 반영하기때문에 멱등성을 띄지만 PATCH는 일부 자원의 증감 등의 역할을 한다면 멱등성을 띄지 않기 때문에 사용에 유의해야 한다.
그러나 이런 모든 것들은 서버에서 메서드를 받고 그 메서드를 어떤 방식으로 구현하고 처리하느냐에 따라 달라지기 때문에 메서드는 그저 리소스를 처리하는 의도를 전달하는 목표를 가지고 있음을 명심하고 구현해야 한다.