모든 개발자를 위한 HTTP 웹 기본 지식 : HTTP METHOD

jkky98·2024년 7월 4일
0

HTTP

목록 보기
5/7
post-thumbnail

좋은 URI 설계

URI설계에서 가장 중요한 것은 리소스 식별이다. 이 리소스의 의미는 "회원정보를 등록하라", "회원정보를 조회하라", "회원정보를 일부 수정하라"와 같은 요청에서 회원정보에 해당한다. 이 회원정보를 URI에 매핑하고 나머지 행동 부분에 해당하는 인간의 문법에서 동사에 해당하는 것들을 Method로 활용할 수 있다.

  • 회원 목록 조회 /members
  • 회원 조회 /members/{id}
  • 회원 등록 /members/{id}
  • 회원 수정 /members/{id}
  • 회원 삭제 /members/{id}

위의 URI 구조에서 목록 조회를 제외한 조회, 등록, 수정, 삭제의 경우에는 모두 URI가 동일하다. 하지만 작업해야할 행동은 다른데 이를 HTTP method로 구분할 수 있다.

HTTP Method

GET

GET /search?q=spring&hl=ko HTTP/1.1
Host: www.google.com

GET은 위와 같이 HTTP 메시지에 포함되어 패킷에 담겨 요청 절차를 가진다. GET의 의미는 리소스를 조회하겠다는 표현이다. 만약 조회를 위해 서버에 추가적으로 데이터를 전달하고 싶다면, query를 통해서 전달한다.(q=spring&hl=ko) 메시지 바디를 사용해서 데이터를 전달할 수 있지만 지원하지 않는 곳이 많아서 권장되는 방법이 아니다. 항상 url에 쿼리 파라미터로 주도록 하자.

POST

POST /members HTTP/1.1
Content-Type: application/json
{
"username": "spring",
"age": 25
}

POST는 CREATE라기 보다 정확히는 http message body를 통해 서버로 들어오는 데이터를 "처리"하라는 메서드이다. 주로 신규 리소스 등록이나 프로세스 처리에 사용된다.

들어온 바디 데이터를 어떻게 처리하는가는 순전히 리소스쪽의 몫이다. 즉 정해진 것이 없다. 새 리소스를 생성할 수도 있고 생성되지 않을 수도 있다. 단순히 들어온 바디 데이터로 리소스를 생성하지 않는 다른 논리의 처리만 진행될 수도 있다.

다른 메서드로 처리가 애매한 경우 애매함을 잘 표현하는 POST로 처리할 수 있다.

PUT

PUT /members HTTP/1.1
Content-Type: application/json
{
"username": "spring",
"age": 25
}

PUT은 요청 데이터의 형식이 POST와 크게 다르지 않다. 리소스를 "완전히" 대체하는 개념이다. 리소스가 없다면 생성하고, 이미 생성되어 있다면 덮어버린다. 그리고 가장 중요한 개념이 클라이언트가 리소스를 식별한다는데에 POST와 큰 차이점이 있다. 서버에서 리소스를 찾아서 덮던가 생성하는 것이 아니라 클라이언트가 요청시 지정한 url로 가서 덮던가 생성하는 것이 PUT이다.

PUT은 리소스를 완전히 대체하므로 만약 위의 http message에서 age만 담긴 json을 보낸다면 /members 에 username이 있을 경우 이는 사라질 것이다.

PATCH

그래서 등장한 것이 PATCH이다. PUT의 경우 수정이라기엔 사실상 새로 만드는 개념같기 때문에 PATCH가 후에 등장한다. 리소스의 부분만을 변경하며 변경될 부분만 지정해서 넘겨주면 해당 리소스에서 넘어온 PATCH와 바디데이터를 보고 자신의 수정이 필요한 부분을 고친다.

DELETE

리소스 제거

HTTP Method의 속성

안전(safe)

호출해도 리소스가 변경되지 않는 메소드를 안전에 해당한다고 말할 수 있다. 누군가는 "악의적으로 계속 호출해서 로그같은것에 의해 서버가 장애가 발생하면요?"라고 하겠지만 "안전"이라는 속성은 리소스만 고려하며 그러한 범주까지 고려하지 않는다.

멱등(Idempotent)

몇 번을 호출하든 1만번을 호출하든 결과가 똑같다면 멱등 메서드이다. GET은 당연히 멱등이며 PUT또한 그러하다. 과정이 어떻게 될지는 모르지만 결과는 항상 PUT이 넘겨준 것으로 대체된다. DELETE도 마찬가지다. 하지만 POST의 경우 멱등이라 할 수 없다. 만약 POST의 메세지 바디 처리가 결제시도라면, 1만번을 시도하면 A손님의 카드로 B물품을 1만번 결제 시도가 될 것이다.(끔찍하다.) 결과가 시도마다 바뀔 수 있으므로 POST는 멱등의 특성을 가지지 않는다.

캐시가능(Cachable)

응답 결과 리소스를 캐시해서 사용해도 되야 캐시 기능을 편하게 사용할 수 있다. GET의 경우 만약 요청 메세지가 같다면 굳이 HTTP 통신으로 하여금 서버에서 응답 데이터를 받을 것이 아니라 이전 응답에 의한 응답 메세지가 캐싱되어있다면 캐시에서 꺼내올 수 있을 것이다. 이러한 방식을 완전 캐시 히트 (Full Cache Hit)라고 한다.

캐시를 활용하여 서버와의 최소한의 통신만 하는 조건부 요청이 가능하다. 만약 캐시를 이용할 수 있는 GET요청이지만 이전 요청과 요청조건이 다르다면 서버와의 최소한의 통신으로 응답 데이터가 이전과 같은 지 확인하고 같다면 캐시에서 이전 응답을 꺼내오는 것이다.

POST를 생각해보자. POST는 body message를 처리한다고 했다. 즉 GET과 달리 body message가 추가된다. 아래는 "만약 POST작업을 캐싱한다면"의 예시이다. 캐시는 key:value 구조를 가진다.

만약 url을 key로 사용한다면 body message가 달라질 경우 동일한 작업이 보장되지 않는다.

/api/submit: POST /api/submit {"username": "user1", "password": "pass1"}

/api/submit: POST /api/submit {"username": "user2", "password": "pass2"}

보통 HTTP 캐시는 요청을 구분하는 주요 키로 URL을 사용한다. POST 요청의 본문은 URL과는 별도로 고유한 캐시 키를 구성해야 하며, 이는 복잡성과 추가적인 관리를 필요로 한다.

즉 GET보다 POST가 다뤄야할 변수가 많기에 상태를 저장하는 것이 유리하지 않을 확률이 더 높다는 것이다. POST는 응답 메시지를 캐싱하기에도, 요청 메시지를 캐싱하기에도 난이도가 높아진다.

출처 : https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard

profile
펑크레코즈

0개의 댓글