본문 바로가기
BackEnd/Server

[RESTful] API 설계 PUT vs PATCH

by 푸고배 2021. 8. 24.

API Endpoint를 설계할 때 항상 CRUD(Create, Read/Retrieve, Update, Delete) 작업에 사용할 HTTP 메서드를 지정해야 한다.

일반적으로 다음과 같이 정리된다.

  • Create : POST
  • Read/Retrieve : GET
  • Update : PUT/PATCH
  • Delete : DELETE

Update의 경우 PUT과 PATCH 두 가지 매서드가 존재하는데, 두 방법 모두 한 Location에서 리소스를 업데이트하는 역할을 하지만 방식이 다르다. 여기서 말하는 '한 Location에서 리소스를 업데이트'란 무엇을 뜻하는 것일까?

태양열 조립식 스웨덴 주택(https://inhabitat.com)

HTTP Request 대상을 "resource(리소스)"라고 부르는데, 리소스는 문서, 사진 그 어떤 객체든 될 수 있으며 각 리소스는 HTTP 전체에 사용되는 URI(Uniform Resource Identifier)에 의해 식별된다. 웹에서 리소스에 대한 식별과 위치는 대부분 단일 URL(Uniform Resource Locator, URI의 한 종류)로 제공된다. 우리는 여기서 URL 개념만을 이용해 설명하고자 한다.

 

인터넷이 거리이고, 거리의 주택은 조립식이며 주택 주소는 URL이라고 가정해본다. 또한, 거리는 숫자로 구별되는 구역으로 이루어져있고, 구역 당 주택이 있어 주택1은 구역1(plot-1)에 있다. 

 

조립식 주택이 있는 https://internet-street.com/plot-1에 PUT 요청을 하면 "plot-1로 표시된 위치에 이 집을 PUT하세요"라는 의미이다. 해당 명령은 지정된 위치에 대한 거리를 검색하고 해당 위치의 내용을 바꾼다. 해당 위치에서 아무것도 발견되지 않으면 해당 위치에 리소스를 PUT한다. 이 경우의 주택은 모든 구조를 포함하는 완전한 조립식 주택이어야 한다.(즉, 주택의 바꿀 부분만 작성하면 안된다. 바꿀 부분을 포함한 주택의 전체 구조를 넣어주어야한다.) 따라서 PUT 요청에는 항상 전체 리소스가 포함된다. 이는 PUT 요청의 필수 조건이 멱등성(같은 요청을 여러번 수행하더라도 동일한 결과를 생성하는 성질)이기 때문이다.

 

예를 들어 해당 위치에 있는 주택에 새 창을 추가하고 싶은 경우 창 개수만 변경되고, 문이나 집의 구조와 같은 조립품은 변경되지 않은 주택으로 PUT 요청을 해야한다. 생각해보면, 집의 창에 대한 속성만 변경하고 싶은데, 변경되지 않는 속성까지 전달해줘야하니, 낭비가 발생한다. 주택에 대한 PUT 요청 페이로드는 아래와 같다.

 

// House on plot 1
{
  address: 'plot 1',
  owner: 'segun',
  type: 'duplex',
  color: 'green',
  rooms: '5',
  kitchens: '1',
  windows: 20
}
// PUT request payload to update windows of House on plot 1
{
  address: 'plot 1',
  owner: 'segun',
  type: 'duplex',
  color: 'green',
  rooms: '5',
  kitchens: '1',
  windows: 21
}

우리는 간단하게 변경될 속성에 관련된 정보만 보내고 서버 코드에서 업데이트 리소스를 적절하게 지정할 수 있지만, 그러면 원래 요청이 실패할 때 네트워크의 응답을 안정적으로 캐싱하고 리소스를 안정적으로 업데이트하는 것과 같은 효율성과 이점을 잃게 된다. PUT 요청은 주요 업데이트에 특히 유용하다. 그렇다면, 웹의 선량한 시민이 되는 동시에(종속성을 깨지 않고)  주택(리소스)에 대한 사소한 업데이트를 어떻게 해야할까? REST 아키텍처의 사후 개념인 PATCH를 설명한다.

 

EDIT : PUT 요청에 대한 응답을 캐시할 수 없다. PUT 요청이 캐시 인프라에서 응답을 찾는 경우 해당 응답(캐시 항목)은 오래된 응답으로 간주해야 한다.

 

HTTP(Hypertext Transfer Protocol)를 확장하는 여러 응용 프로그램에는 부분적인 리소스 수정을 수행하는 기능이 필요하다. 기존 HTTP PUT 방법은 문서의 완전한 교체만 허용한다. 이 제안은 기존 HTTP 리소스를 수정하기 위해 새 HTTP 메서드 PATCH를 추가한다.

 

반면에 PATCH 요청은 위치에서 리소스의 일부를 변경하는데 사용된다. 즉, 리소스를 PATCH하여 속성을 변경한다. 리소스의 일부를 업데이트하는데 사용되며 멱등성이 필요하지 않다.

 

위의 예를 계속 사용하면 창 속성을 변경하기 위해서 전체 집을 배송할 필요없이 구역1의 집에 새 창을 쉽게 추가할 수 있다. 우리가 해야할 일은 창을 배송하고 기존의 집에 새 창을 패치하는 것 뿐이다. 아래는 우리가 보내야하는 페이로드의 예이다.

 

// House on plot 1 (same as above)
{
  address: 'plot 1',
  owner: 'segun',
  type: 'duplex',
  color: 'green',
  rooms: '5',
  kitchens: '1',
  windows: 20
}
// Patch request payload to update windows on the House
{
  windows: 21
}

 

PATCH는 멱등성(종속성)이 없으므로 실패한 요청은 네트워크에서 자동으로 다시 시도되지 않는다. 또한 PATCH 요청이 존재하지 않는 URL에 만들어진 경우(예: 존재하지 않는 건물의 문을 교체하려는 경우), PUT과는 달리 새로운 리소스를 만들지 않고 실패해야 한다. (집은 없는데 문만 있으면.. 이상하잖아요)

 

참고자료 :

 

RESTful API Design — PUT vs PATCH

When designing API endpoints, there’s always the need to specify what http method to use for CRUD (Create, Read/Retrieve, Update, Delete) operations. In this article, Segun explains the nuances of HTTP PUT and PATCH methods.

blog.segunolalive.com

 

웹 리소스 식별 - HTTP | MDN

HTTP 요청 대상을 "리소스"라고 부르는데, 그에 대한 본질을 이 이상으로 정의할 수 없습니다; 그것은 문서, 사진 또는 다른 어떤 것이든 될 수 있습니다. 각 리소스는 리소스 식별을 위해 HTTP

developer.mozilla.org

 

 

 

반응형

댓글