HTTP의 URI로 리소스를, HTTP Method로 리소스에 대한 행위를 나타내기에 이해하기 쉬운 장점을 극대화한 REST API와 같은 아키텍쳐를 이해하기 위해서 HTTP Method에 대해 알아본다.
HTTP Request Method
서버의 CRUD기능을 구현할 때 CREATE는 POST, READ는 GET, UPDATE는 PUT or PATCH, DELETE는 DELETE를 사용한다. HTTP Request 구조자체는 GET을 제외하고는 동일하다.
서버에서 동일한 구조에서 데이터를 Method에 따라 달리 이용하는 방법을 정의하기 위해 Method가 존재한다고 할 수있다.
GET
URI로 지정된 리소스에서 데이터를 서버에 요청한다.
- 쿼리 스트링으로 URI에 원하는 정보를 요청한다.(바디 없음)
- 캐싱 가능
- 길이 제한 있음
- 데이터 요청만(수정 불가)
GET 요청 메소드에 바디를 첨가 할 수 있지만 다음과 같은 이유로 사용을 지양한다.
- 캐싱 안될 수 있음
- RESTful 설계와 맞지 않음
- 지원하지 않는 서버, 클라이언트 존재
조회에 적합하게 데이터를 요청만 하도록 설계되었고, 캐싱으로 조회성능을 높인다.
HEAD
GET과 동일하지만 서버에서 바디를 리턴하지 않는다.
- 리소스를 받지 않고 찾기만 하거나 응답 상태코드를 확인
POST
리소스를 생성/업데이트 하기 위해 서버에 데이터를 보낼 때 사용한다.
- 바디에 데이터를 담아 GET보다 상대적으로 안전하지만, 요청 내용을 확인할 수 있기에 암호화가 필요
- 바디의 타입인 Content-Type 명시
- 길이 제한 없음
생성에 적합하게 같은 요청을 해도 계속적인 리소스의 추가가 일어난다.
TRACE
클라이언트로부터 리퀘스트 패킷이 방화벽, 프록시 서버, 게이트웨이를 거치면서 패킷의 변조가 일어날 수 있는데 서버에 도달 했을 때의 최종 패킷의 리퀘스트 패킷을 볼 수 있다.
OPTION
URL에 해당하는 서버의 지원가능한 메소드를 알아볼 수 있다.
PUT
새로운 리소스 생성하거나 대상 리소스를 대체하기 위해 사용한다.
리소스가 없으면 생성, 있으면 해당 리소스로 대체하기 때문에 같은 요청을 반복하면 같은 효과를 보여 멱등성을 가진다.
수정에 적합하게 리소스가 존재하면 대체하고, 존재하지 않아도 해당 리소스로 대체한다.
POST와 같이 저장하려는 엔티티의 전체를 보내야 한다.
PATCH
PUT과 달리 리소스의 완전한 교체가 아닌 일정부분을 수정하기 위해 사용
멱등성을 가지지 않는데 PUT과 같이 사용해 멱등성을 가지게 할 수도있음
PUT과 달리 업데이트하려는 필드만 보낸다.
DELETE
해당 리소스를 삭제하기 위해 사용
PUT vs PATCH
PUT은 알고 사용하던 대로였는데 지금까지 사용하는 PATCH 자체가 멱등성을 가지는줄 알았고 그렇게 써온 예시를 먼저 보겠다.
1. 저장된 리소스
{ref - RFC 7936
"title": "Goodbye!",
"author" : {
"givenName" : "John",
"familyName" : "Doe"
},
"tags":[ "example", "sample" ],
"content": "This will be unchanged"
}
2. PATCH Request
PATCH /my/resource HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"title": "Hello!",
"phoneNumber": "+01-123-456-7890",
"author": {
"familyName": null
},
"tags": [ "example" ]
}
3. 수정된 리소스
{
"title": "Hello!",
"author" : {
"givenName" : "John"
},
"tags": [ "example" ],
"content": "This will be unchanged",
"phoneNumber": "+01-123-456-7890"
}
위의 요청은 여러번 요청해도 같은 결과는 갖는 멱등성을 갖는 JSON Merge PATCH 방식이다.
하지만 RFC 5789에 따르면
With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources
PATCH는 요청에 포함된 엔티티는 새로운 버젼의 생성을 위해 서버에 있는 원본 리소스가 어떻게 수정되어야 하는지 나타내는 지시의 집합이고 다른 resource에 사이드 이펙트를 일으킬 수 있도록 설계되었다고 한다.
그 예시는 아래와 같다.
PATCH /file.txt HTTP/1.1
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 100
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
replace, move, copy 등과 같이 리소스 자체에 대한 수정이 아니라 리소스의 행위를 지시하는 경우 업데이트 된 부분 외에도 사이드 이펙트를 일으킬 수 있고 멱등성을 가지지 않는다는 것이다.
JSON Merge와 같이 리소스의 상태를 변경하는 보통의 경우는 멱등성을 갖는 PATCH,
리소스의 행위를 지시하는 경우는 멱등성을 갖지않는 PATCH임을 알고 설계할 때 후자의 경우라면
사이드 이펙트가 있을 수 있다는 걸 알고 설계해야 할 것이다.
참조
https://www.w3schools.com/tags/ref_httpmethods.asp
https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/POST
https://www.qu3vipon.com/idempotence-of-patch
https://www.rfc-editor.org/rfc/rfc5789#section-2
https://medium.com/@lyhlg0201/http-method-d561b77df7