HTTP

4. HTTP 메서드

zuun 2022. 7. 28. 17:53

회원 정보를 관리하는 HTTP API를 만들어보고자 한다.

CRUD 기능을 기본으로 하는 API를 만들어볼 것이다.

우선, API를 만들기 전에 정해야 할 것은 URI이다.

예를 들어, "회원 조회"라는 기능에 대한 URI를 "/read-member-by-id"로 정하면 어떨까 ?

분명, URI를 보았을때 해당 기능을 알 수 있는 것은 분명하다.

하지만, 우리는 URI가 Resource를 식별해주는 식별자로써의 역할을 한다는 것을 배웠다.

그렇다면, 회원 정보를 관리하는 메서드에서 Resource는 무엇일까 ? 바로 회원이다.

여기서 우리는 "/members/id" 처럼 구현하면 되겠구나 ! 라고 생각할 수 있다.

하지만, 회원 정보를 관리하는 API에 회원 추가, 삭제, 수정 등의 기능도 위와 같은 형태로 나타내야한다.

그렇다면, 동일한 URI를 보고 기능을 어떻게 구분해야할까 ?

정답은 아래에 있다.


HTTP 메서드

● GET

Resource를 조회하기 위한 메서드이다.

서버에 전달하고 싶은 데이터는 query를 통해 전달할 수 있다.

Message Body를 통해 데이터 전달을 할수도 있지만, 지원하지 않는 경우도 다수 존재한다.

GET /members/100 HTTP/1.1
Host: localhost:8080

※ 요청 메세지(Request Message)

 

위와 같이 요청 메세지(Request Messgae)를 보내면, 서버에서 해당 메세지에 해당하는 응답 메세지(Response Meesage)를 보내준다.

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 93
{
Message Body..
}

※ 응답 메세지(Response Message)

● HEAD

GET 메서드와 동일하지만, 응답 메세지로 Message Body를 제외한 Status line 과 Header만 반환한다. 

● POST

서버에 데이터를 보내서,  해당 데이터를 기반으로 데이터를 처리하고자 할 때 사용하는 메서드이다.

서버에서는 Message Body를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다. (Create, Update 등)

POST /members HTTP/1.1
Content-Type: application/json
{
Message Body..
}

※ 요청 메세지(Request Message)

 

POST 메서드를 사용할 경우, 클라이언트와 서버사이의 임의의 약속을 맺어야 한다.

예를 들어, "/members"라는 URI를 사용하면 새로운 정보를 추가할 것이다. 라고 약속을 해야한다.

같은 POST 메서드를 사용하더라도, 약속한 URI에 따라 정보의 추가가 일어날 수도, 변경이 일어날 수도 있는 것이다.

(따로 정해진 규약은 없다)

 

HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 34
Location: /members/100
{
Message Body..
}

※ 응답 메세지(Response Message)

 

POST 메서드의 경우, 단순히 Resource를 조회하는 GET메서드와 달리, 상황에 따라 다르게 동작한다.

그렇다면, 언제 POST 메서드를 사용하는 것이 좋을까 ?

1. 새로운 Resource 등록

2. 프로세스 처리 (프로세스 상태 변경)

단순히 값을 변경하는 것이 아니라, 동작 흐름 자체가 바뀌는 경우 사용한다.

※ POST의 결과로 새로운 Resource가 반드시 생기는 것은 아니다.

분명, 위에서 URI를 설계할 때 단순히 Resource만을 구분할 수 있도록 설계하라고 하였다.

하지만, 현실적으로 불가능한 순간이 존재한다.

이럴 경우에는 예외적으로, 컨트롤 URI로 설계하여 동작을 구분해주면 된다.

(이랬다 저랬다.... ㅠㅠ)

3. 다른 HTTP 메서드로 처리하기 애매한 경우

다른 메서드를 사용하기 애매하다 싶으면 POST 메서드를 사용하면 대부분 해결이 가능하다.

ex) JSON 타입으로 조회 데이터를 넘기고자 하는 경우, Message Body를 지원하지 않는 GET 메서드 대신 POST 메서드 사용

 

POST는 모든 것을 할 수 있다. 하지만, 단순히 데이터를 조회하는 경우에는 GET 메서드를 사용하는 것이 유리하다.

서버에서는 GET 메서드로 오면, 캐싱을 하겠다는 일종의 약속을 한다. (속도 향상의 이유로)

POST 메서드로 온 것을 캐싱하는 것이 어렵기 때문에, 단순 조회 기능은 GET 메서드를 사용하는 것이 좋다.

● PUT

Resource를 대체하는 메서드이다.

Resource가 이미 존재하면, 완전히 대체하고 존재하지 않으면 새로 생성한다.

"완전히 대체"한다는 것에 주목할 필요가 있다. PUT은 단순히 Update하는 동작이랑 다르다.

예를 들어, 이미 존재하는 Resource에 필드 A,B가 있다고 가정하자.

PUT 메서드를 통해, A 필드에 대한 정보만 요청할 경우, 이미 존재하던 Resource에서 B 필드자체가 사라진다.

POST와 다른 점은 클라이언트가 Resource의 위치를 정확히 알고 URI를 지정한다는 것이다.

POST에서는 상위 계층을 URI로 지정하는 반면, PUT은 클라이언트에서 정확한 URI를 지정한다.

PUT /members/100 HTTP/1.1
Content-Type: application/json
{
Message Body..
}

※ 요청 메세지(Request Message)

그렇다면, Update 동작을 하기 위해서는 어떻게 해야할까?

PATCH 메서드를 사용하면 된다 !

● PATCH

Resource를 부분 변경하고자 할때 사용한다. (Update)

특정 Resource의 일부 데이터만 넘기더라도, "완전 대체"되는 PUT 메서드와는 다르게 Update된다.

PATCH /members/100 HTTP/1.1
Content-Type: application/json
{
Message Body..
}

※ 요청 메세지(Request Message)

● DELETE

메서드명 그대로, Resource를 삭제하고자 할때 사용된다.

DELETE /members/100 HTTP/1.1
Content-Type: application/json
{
Message Body..
}

※ 요청 메세지(Request Message)


HTTP 메서드 속성

출처 : https://ko.wikipedia.org/wiki/HTTP

● 안전

해당 메서드를 호출해도 Resource가 변경되지 않는 것을 "안전하다"라고 한다.

● 멱등(Idempotent)

호출 횟수에 상관없이, 결과가 똑같은 것을 "멱등"이라고 말한다.

GET : 단순 조회이기 때문에, 호출 횟수에 상관없이 결과가 동일하다.

PUT : "완전 대체"하기 때문에, 같은 요청을 여러번 해도 최종 결과는 동일하다.

DELETE : Resource를 삭제하기 때문에, 같은 요청을 여러번 해도 최종 결과는 동일하다.

POST : 경우에 따라(결제 URI 등) 호출 횟수에 따라 결과가 다를 수 있다.

이러한 멱등을, "자동 복구 메커니즘"에 적용하여 사용할 수 있다.

ex) DELETE 메서드를 통해 요청하였는데, 응답이 없을 경우 재 요청해도 문제가 없기 때문에

● 캐시 가능(Cacheable)

응답 Resource를 캐시해서 사용해도 되는가 ?에 대한 항목이다.

GET, HEAD, POST, PATCH가 캐시 가능하다고 되어 있지만, Message Body를 포함하여 캐시 키를 고려하는 것이 어렵기 때문에, 실질적으로는 GET과 HEAD 메서드만 캐시로 사용한다.