클라이언트가 서버에 리소스를 요청할 때 사용(CRUD에서 Read)
클라이언트가 서버의 리소스를 새로 만들 때 사용(CRUD에서 Create)
클라이언트가 서버의 리소스를 수정 할 때 사용(CRUD에서 Update : 전체 수정)
클라이언트가 서버의 리소스를 수정 할 때 사용(CRUD에서 Update : 일부 수정)
PUT의 경우 자원 전체를 갱신하는 의미지만, PATCH는 해당자원의 일부를 교체하는 의미로 사용.
PATCH는 항상 idempotent하지 않는다. 즉, idempotent이기도 하나 어쩔때는 아닐 때도 있다.
idempotent
수정할 자원의 식별자를 명시하고, 수정할 데이터를 명시해서 요청을 보내는 경우
PATCH https://localhost:8080/api/users/1
# Original resource
{"name": "Tito", "age": 32}
# PATCH request
{"age": 33}
# New resource
{"name": "Tito", "age": 33}
# Original resource
{"name": "Tito", "age": 32}
# PATCH request
{ $increment: "age"}
# New resource
{"name": "Tito", "age": 33}
클라이언트가 서버의 리소스를 삭제 할 때 사용(CRUD에서 Delete)
클라이언트가 서버에서 해당 URL이 어떤 메소드를 지원하는 확인할 때 사용
예를 들어, /update uri에서 어떤 method를 요청 가능한가(GET? POST?)를 알고 싶으면 먼저 OPTIONS 요청을 사용해서 확인
GET과 유사한 방식이나 웹 서버에서 헤더 정보 이외에는 어떤 데이터도 보내지 않는다.
이에 따라 HTTP response은 body없이 HTTP header 정보만을 보낸다.
웹 서버의 다운 여부 점검(Health Check)이나 웹 서버 정보(버전 등)등을 얻기 위해 사용될 수 있다.
GET과 동일하지만 서버에서 Body를 Return 하지 않음
요청한 리소스에 대해 양방향 연결을 시작하는 메소드
클라이언트는 원하는 목적지와의 TCP 연결을 HTTP 프록시 서버에 요청한다. 그러면 서버는 클라이언트를 대신하여 연결의 생성을 진행한다. 한번 서버에 의해 연결이 수립되면, 프록시 서버는 클라이언트에 오고가는 TCP 스트림을 계속해서 프록시한다.
클라이언트와 서버간 통신 관리 및 디버깅을 할 때 사용
f(f(x)) = f(x)
멱등 : 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질
결과부터 말하자면
POST는 idempotent하지 않고, 매번 새로운 리소스가 생긴다.
PUT은 idempotent하고, 몇 번을 수행하더라도, 같은 결과를 보장한다.
예를 들어
POST
HTTP /user POST/1.1
{"name": "홍길동", "email": "foo@gmail.com"}
HTTP/1.1 201 Created
위 요청을 보내면 /user/1
에 생기고, 또 보내면 /user/2
, /user/3
, ... 등 매번 다른 곳에 새로운 리소스가 생성될 수 있으므로, POST는 idempotent하지 않다.
PUT
HTTP /user/1 PUT/1.1
{"name": "홍길동", "email": "foo@gmail.com"}
HTTP/1.1 200 OK
위 요청을 보면 알 수 있듯이 자원의 식별자를 미리 알고 있는 상태여야하고, 위 요청을 여러번 보내도 같은 결과를 보장하기 때문에, PUT은 idempotent하다.
물론 꼭 PUT에 식별자를 포함할 필요는 없으므로 존재하지 않는 식별자로 요청을 하게 되면 이때는 POST와 동일하게 자원을 생성한다. 하지만 두번째 요청에서 생성된 자원이 있으므로 자원을 생성하지 않고 교체하게 된다.
GET | POST | |
---|---|---|
History | 파라미터들은 URL의 일부분이기 때문에 브라우저 히스토리에 남는다. | 파라미터들이 브라우저 히스토리에 저장되지 않는다. |
Boomarked | 요청 파라미터들이 URL로 인코딩되므로 즐겨찾기가 가능하다. | 요청 파라미터들이 request body에 포함되고 request URL에 나타나지 않으므로 즐겨찾기가 불가능하다. |
re-submit behaviour | GET 요청이 다시 실행되더라도 브라우저 캐시에 HTML이 저장되어 있다면 서버에 다시 submit되지 않는다. | 브라우저가 보통 사용자에게 데이터가 다시 submit되어야 한다가 alert을 준다. |
Encoding type | application/x-www-form-urlencoded | multipart/form-data or application/x-www-form-urlencoded Use multipart encoding for binary data. |
parameters | 전송 가능하지만 URL에 넣을 수 있는 파라미터 데이터가 제한된다. 2K이하로 사용하는 것이 안전하며 몇몇 서버들은 64K까지 다룬다. | 서버에 파일 업로드하는 것을 포함하여 파라미터를 전송할 수 있다. |
Hacked | script kiddies에 의해 해킹되기 쉽다. | GET에 비해 좀 더 해킹하기 어렵다. |
Restrictions on form data type | 오직 ASCII characters만 허용된다. | 제한이 없다. binary data도 허용된다. |
Security | GET은 POST에 비해 보안에 약하다. 그 이유는 데이터가 URL의 일부로 전송되고 그 때문에 브라우저 히스토리에 저장되며 서버가 플레인 텍스트로 로그를 남기기 때문이다. | POST는 GET에 비해 보안에 조금 더 안전하다. 그 이유는 파라미터들이 브라우저 히스토리나 서버 로그에 저장되지 않기 때문이다. |
Restrictions on form data length | form data가 URL에 포함되고 URL 길이가 제한되기 때문에 form data의 길이도 제한된다. 안전한 URL 길이는 2048 characters이나 브라우저나 웹 서버에 따라 달라진다. | 제한이 없다. |
Usability | GET 메소드는 비밀번호와 같은 민감한 정보들을 전송하는데 사용해선 안된다. | POST 메소드는 비밀번호와 같은 민감한 정보를 전송하는데 사용된다. |
Visibility | GET 메소드는 모두에게 보여진다. (브라우저의 주소창에 그대로 보여지고 그에 따라 전송가능한 정보의 양도 제한된다.) | POST 메소드는 URL에 보여지지 않는다. |
Cached | GET은 idempotent하기 때문에 캐시가 된다.(같은 요청을 여러 번 보내도 항상 같은 응답이 온다.) | POST는 idempotent하지 않기 때문에 캐시가 되지 않는다.(같은 요청을 여러 번 보내도 다른 응답이 올 수 있다.) |
참고
http://1ambda.github.io/javascripts/rest-api-put-vs-post/
https://im-developer.tistory.com/166
https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/CONNECT
https://softwareengineering.stackexchange.com/questions/260818/why-patch-method-is-not-idempotent