[HTTP] HTTP 메서드

2024. 3. 20. 01:38네트워크/웹

대부분의 내용은 인프런 김영한 강사님의 모든 개발자를 위한 HTTP 웹 기본 지식을 참고했습니다.


이전 글인 HTTP 메시지의 구조에 대해서 설명하면서 HTTP 메서드라는 것이 나왔습니다.

이 글에서는 HTTP 메서드에 대해서 자세히 설명하겠습니다.

 

HTTP API 설계

 

회원과 관련된 HTTP API를 설계한다고 가정하고 아래와 같은 URI를 만들어봅시다.

회원 목록 조회 : read-member-list
회원 조회 : read-member-by-id
회원 등록 : create-member
회원 수정 : update-member
회원 삭제 : delete-member

우선, 이렇게 만든 URI는 잘 만든 URI인지부터 생각해보아야 합니다.

이전에 URI에 대해서 작성했던 글에도 나와있듯이 URI는 자원의 식별에 사용되어야 합니다.

하지만 설계된 URI는 회원이라는 자원에 대한 행동이 포함되어 있어 회원이라는 자원을 식별한다는 것에 중점을 두지 않아

잘못된 설계방법입니다.

 

그래서 다시 설계를 한다면 아래와 같습니다.

회원 목록 조회 : /members
회원 조회 : /members/{id}
회원 등록 : /members/{id}
회원 수정 : /members/{id}
회원 삭제 : /members/{id}
* 계층 구조상 상위를 컬렉션으로 보고 복수단어를 사용.

이제 회원이라는 자원을 식별할 수 있도록 URI를 설계했습니다. 하지만, 하나의 문제가 더 생깁니다.

URI로 자원을 식별해서 나타냈으나 해당 자원에 대해 어떤 행동을 하는지에 대한 구분이 없습니다.

이렇게 어느 자원에 대한 행동을 구분해야 할 때 사용하는 것이 HTTP 메서드(HTTP Method)입니다.


HTTP 메서드의 종류와 설명

 

HTTP 메서드는 주로 사용되는 GET, POST, PUT, PATCH, DELETE가 있습니다.

(이외에 HEAD, OPTION, CONNECT, TRACE가 있습니다.)

 

GET

리소스를 조회할 때 사용합니다.

GET /search?q=hello HTTP/1.1  
Host: www.google.com

 

GET 요청에서 서버에 전달하고 싶은 데이터는 URI의 끝에 query(쿼리 파라미터 또는 쿼리 스트링)를 통해서 전달합니다.

쿼리 스트링은 'key=value' 형태로 구성되며 여러 개의 key=value는 '&'로 구분합니다.
Message Body를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않습니다.


POST

주로 새로운 리소스를 생성하거나 요청 데이터를 처리할 때 사용합니다.

POST /member HTTP/1.1  
Content-Type: application/json
{
  "username": "hello",
  "age": 20
}

POST 요청은 데이터를 본문(Messge Body)에 담아서 서버로 전송합니다.

사용자의 로그인 정보, 결제 정보 등 보안적인 정보는 GET 메서드를 사용하지 않고 POST 요청을 통해 전송합니다.

 

조회를 하는 경우에도 POST를 사용하는데, JSON으로 조회 데이터를 넘겨야 할 때 GET은 body를 지원하지 않는 곳이 많으므로,

이런 경우에는 POST로 조회요청을 하기도 합니다.

이렇게 다른 메서드로 처리하기 어려운 경우 보통 POST를 사용합니다.


PUT

새로운 리소스를 생성하거나 기존 리소스를 업데이트하도록 요청할 때 사용합니다.

PUT /member/100 HTTP/1.1  
Content-Type: application/json
{
  "username": "hello",
  "age": 20
}

PUT의 경우는 기존 리소스가 있으면 대체하고 없다면 생성합니다.

(일반적으로 성공한 경우 200 OK를 반환하거나 새로운 리소스가 생성된 경우 201 Created를 반환합니다.)

POST와 차이점은 요청을 보내는 클라이언트가 리소스의 정확한 위치를 알고 식별해 URI를 지정해야 한다는 것입니다.

(위의 예시와 같이 /member/100 이런 식으로)

PUT은 기존의 리소스를 완전히 대체하므로 부분만 변경할 때는 PATCH를 사용해야 합니다.


PATCH

리소스의 일부분을 업데이트할 때 사용합니다.

PATCH /member/100 HTTP/1.1  
Content-Type: application/json
{
  "age": 20
}

PUT과 다르게 리소스의 일부분을 업데이트합니다.


DELETE

리소스를 삭제할 때 사용합니다.

DELETE /member/100 HTTP/1.1  
Content-Type: application/json

 


HTTP 메서드의 속성

이미지 출처 https://en.wikipedia.org/wiki/HTTP

HTTP 메서드의 속성에는 안전(Safe Methods), 멱등(Idempotent Methods), 캐시가능(Cacheable Methods)이 있습니다.

 

안전(Safe)

안전한 메서드는 호출해도 리소스가 변경되지 않는 것을 말합니다.

주로 리소스를 읽는 GET 메서드가 여기에 속합니다.

단순하게 조회를 하는 요청 메서드이니 리소스가 변하지 않기 때문입니다.


멱등(Idenmpotent)

멱등의 개념은 다음과 같습니다.
"수학이나 전산학에서 연산의 한 성질을 나타내는 것으로, 연산을 여러 번 적용하더라도 결과가 달라지지않는 성질"

즉, 동일한 연산을 여러번 수행해도 동일한 결과가 나와야 하는 것을 말합니다.

 

하나씩 살펴봅시다.

1. GET

GET은 몇 번을 호출해도 동일한 결과가 나오기 때문에 멱등합니다.

멱등을 따질 때 외부 요소로 인한 리소스의 변경은 고려하지 않습니다.
오로지 클라이언트 하나가 동일한 요청을 보냈을 때만 고려합니다.
사용자 A : GET -> username: kim, age: 20
사용자 B : PUT -> username: lion
사용자 A : GET -> username: lion
이런 경우 사용자 A는 바뀐 데이터가 조회되지만, 멱등성을 따질 때 이런 경우까지는 생각하지 않습니다.

 

 

2. PUT

PUT 데이터를 덮어씌우기 때문에 몇 번을 호출해도 동일한 결과를 받아 리소스가 동일한 상태를 유지합니다.

 

3. PATCH

PATCH는 멱등하게도 멱등하지 않게도 사용할 수 있기 때문에 멱등하지 않습니다.

∴ 기존의 데이터를 단순히 변경하는 경우에는 멱등할 수 있으나, 기존값에 연산을 해서 데이터를 변경하면 멱등하지 않기 때문입니다.

PATCH를 사용해서 단순히 나이를 20살로 변경한다고 하면 몇 번을 호출해도 나이가 20살이므로 멱등합니다.
PATCH -> age : 20
하지만, 기존의 나이에 20살을 더하도록 설계한다면 멱등하지 않습니다.
PATCH -> age : 20
이렇게 2회 이상 호출하면 나이가 20살 -> 40살 -> 60살... 이렇게 동일한 결과가 나오지 않기 때문입니다.

여기서 PUT도 PUT도 똑같이 나이가 증가하는 PUT 로직이 있다면 멱등하지 않지 않냐 라는 질문이 나올 수 있습니다.
앞서 설명했듯이 PATCH의 용도는 데이터를 부분적으로 변경하는 용도로 사용됩니다.
기존의 어떠한 상태에서 다른 상태로 변경해달라는 요청으로 사용되므로 연산이 들어간 수정이 있어도 정상적으로 사용한다고 할 수 있습니다.
하지만, PUT의 경우에는 목적이 기존의 데이터를 덮어씌워서 데이터를 넣어달라는 요청이므로
PUT을 목적대로 사용했을 때는 멱등하다고 할 수 있습니다.

 

4. POST

당연하게도 멱등하지 않습니다.

데이터를 생성해달라는 요청을 계속 보낸다면 리소스가 동일한 상태이지 않기 때문입니다.

 

5. DELETE

몇 번을 호출해도 삭제된 결과는 똑같기 때문에 멱등합니다.


캐시가능(Cacheable)

캐시가능 메서드는 서버의 응답을 클라이언트에 캐시할 수 있음을 나타냅니다.

 

js, css, 이미지 같은 정적 컨텐츠는 데이터양이 크고 변경될 일이 적기때문에
정적 컨텐츠를 요청하고 나면 브라우저에서 요청을 캐시해두고, 동일한 요청이 발생하면 캐시된 데이터를 사용합니다.

이로써 동일한 요청이 발생할 때 응답을 재사용해 네트워크 대역폭을 절약하고 응답 시간을 줄일 수 있습니다.

캐시는 GET, HEAD, POST, PATCH 캐시가능하나, 실제로는 GET, HEAD 정도만 캐시로 사용합니다.
캐시를 구현하려면 Key가 맞아야하는데 POST, PATCH는 Message Body안의 내용까지 고려해야하기 때문에 구현이 어렵기 때문입니다.

'네트워크 > ' 카테고리의 다른 글

[HTTP] HTTP 헤더 - 전송 방식과 일반 정보 헤더  (0) 2024.04.12
[HTTP] HTTP 헤더 - 표현과 협상  (0) 2024.04.11
[HTTP] HTTP 메세지  (0) 2024.03.19
[HTTP] HTTP의 특징  (0) 2024.03.16
[HTTP] HTTP 정의와 HTTP스펙  (0) 2024.02.22