study/HTTP

HTTP 웹 기본 지식(4) - HTTP 메서드

올스왑 2022. 2. 20. 23:43

이 글은 인프런 김영한 님의 강의 모든 개발자를 위한 HTTP 웹 기본 지식을 듣고 정리하는 글입니다.

 

HTTP API를 설계할 때는 리소스를 중심으로 URI를 설계해야 한다. 예를 들어 회원 관리 API를 설계한다고 했을 때, 리소스는 회원이 되고, 그에 대한 행위는 조회, 등록, 삭제, 수정 등이 된다. 그럼 행위는 어떻게 구분하는가? HTTP 메서드를 통해 구분할 수 있다. 그래서 URI는 리소스만 식별하면 된다.

리소스를 중심으로 회원 조회 URI를 설계했다면 get 요청으로 /members/{id} 정도가 될 수 있지만, 그렇지 않으면 /read-members-by-id/{id} 등이 될 것이다.

 

HTTP 메서드를 알아보자.

  • GET: 리소스 조회
  • POST: 요청 데이터 처리. 주로 등록에 사용.
  • PUT: 리소스를 대체. 해당 리소스가 없으면 생성한다.
  • PATCH: 리소스 부분 변경
  • DELETE: 리소스 삭제
  • 기타 메서드: HEAD - GET과 동일하지만 바디 부분을 제외하고, 상태 줄과 헤더만 반환

 

  • GET
    • 리소스를 조회하는 용도.
    • 서버에 전달하고 싶은 데이터는 쿼리를 통해 전달한다.(쿼리 파라미터, 쿼리 스트링)
    • Get 경우에도 메시지 바디를 사용해서 데이터를 전달할 있지만, 지원하지 않는 곳이 많아서 권장하지 않는다.
    • 동작 예시) 클라이언트가 서버에게 GET으로 요청하면 서버에 요청 메시지가 도착하고, 서버가 응답 메시지를 보내준다.
  • POST
    • 요청 데이터를 처리해달라는 용도다.(요청 해야 할 데이터를 보낸다.)
    • 메시지 바디를 통해 서버로 요청 데이터를 전달한다. 그러면 서버는 요청 데이터를 처리한다.
    • 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
    • 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용한다.
    • 동작 예시) 클라이언트가 POST로 데이터를 보내면 서버는 메시지를 받는다. 그런데 미리 처리한다는 약속이 되어 있어야 한다.(서버: "/members"에 POST로 데이터를 보내주면 멤버를 신규 등록할게) 그러면 서버는 신규로 생성된 리소스의 path도 보내주고, 응답 코드도 보내준다.
    • 그런데 POST는 요청 데이터를 어떻게 처리하라는 것일까? 스펙을 보면 "POST 메서드는 대상 리소스가 리소스의 고유한 의미 체계에 따라 요청에 포함 된 표현을 처리하도록 요청합니다."라고 나와 있다.
    • 정리하면, 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할 것인지 리소스마다 따로 정해야 한다는 것이다.(따로 어떻게 처리하는 건지 정해진것이 아님)
    • 그럼 보통 언제 POST를 사용할까
      • 새 리소스를 생성, 등록할 때
      • 요청 데이터를 처리하게 할 때
        • 단순히 데이터를 생성, 변경하는 것을 넘어 프로세스를 처리해야 하는 경우
        • 예를 들어 주문을 접수 받은 사장님이 "배달 시작" 버튼을 누를 때도 POST를 사용해야 한다.(get, post, put, patch 중에 뭘 쓸게 있나? 없다. 이럴 때 POST를 사용한다. 프로세스를 처리하는 경우니까)
        • POST의 결과로 새로운 리소스가 생성되지 않을 수도 있다.
        • 위에서 "배달 시작"의 URI의 경우 "POST /orders/{orderId}/start-delivery" 라고 지을 수가 있는데, 이렇게 행위가 담겨 있는 URI를 "컨트롤 URI" 라고 한다. 컨트롤은 반드시 동사여야 한다.
      • 다른 메서드로 처리하기 애매할 때
        • 조회용 요청을 보내야 하는데 json을 보내야 되서, get을 못 쓸 때
        • 애매하면 POST
        • 그래도 목적에 맞게 조회용이라면 get을 쓰는게 좋다.
  • PUT
    • 리소스를 대체.(완전 대체)
    • 리소스가 있으면 대체, 없으면 생성이다.
    • 리소스의 일부만 수정하는 것이 아니다. 그래서 전달한 값으로만 리소스가 구성된다.
      • 예를 들어, 이름: 홍길동, 나이: 10 이라는 멤버 정보를 수정하기 위해 나이:20으로만 PUT 요청을 보내면 이름은 사라지고 나이 정보만 남게 된다.
    • 쉽게 말해 덮어쓰기와 비슷하다.
    • 중요한 것은 PUT 요청의 경우, 클라이언트가 리소스를 식별해야 한다.(알고 있어야 한다.)
      • 이것이 POST와의 중요한 차이다.
      • 요청 시, 클라이언트가 리소스 위치를 알고 URI를 지정해야 한다.
    • 수정하기 위해선 당연히 조회처럼, 리소스를 지정해야 한다.
  • PATCH
    • 리소스를 부분만 변경할 때 사용한다. 완전 대체가 아니다.
    • 리소스 정보의 일부만 수정해서 일부만 보내면, 그 정보만 수정되고, 나머지는 그대로 있다.
    • 간혹 PATCH가 지원되지 않는 경우가 있는데, 그럴 때는 POST를 쓰면 된다.
  • DELETE
    • 리소스 제거. 당연히 리소스 식별하고 있어야 한다.

 

HTTP 메서드의 속성이 있다.

  • 안전(Safe methods)
  • 멱등(Idempotent Methods)
  • 캐시가능(Casheable Methods)

 

  • 안전
    • 호출해도 리소스를 변경하지 않는다는 속성이다.
    • 예를 들어, get, head(get이랑 같은 body 없는 ),... -> 이것들은 조회만 하니까 리소스를 변경하지 않는다.
    • Post, delete, put, patch 안전하지 않은 .
    • 그런데 계속 호출해서 로그가 쌓여서 장애가 발성하면? 안전이란 것은 해당 리소스 범위에서만 고려한다.
  •  멱등
    • F(f(x)) =f(x)
    • 한 번 호출하든  번 호출하든 100 호출하든 결과가 똑같다.
    • 같은 호출을 하면 결과는 같아야 한다.
    • Get : 조회하든, 조회하든 같은 결과가 조회된다.
    • Put: 결과를 대체한다. 따라서 같은 요청을 여러번 해도 최종 결과는 같다.
    • Delete: 결과를 삭제한다. 같은 요청을 여러번 해도 삭제된 결과는 똑같다.(한 데이터를 삭제하고 또 삭제 요청해도 결과는 "삭제됨"으로 같다)
    • Post: 이것은 멱등이 아니다. 호출하면 같은 결제가 중복된다.
    • 활용
      • 자동 복구 매커니즘을 생각해보자
      • DELETE를 했는데 결과를 모른다고 하자. 그래서 한번 더 DELETE 요청을 한다고 해도 문제는 없다.
      • 서버가 타임아웃 등으로 정상 응답을 못받을 때, 클라이언트가 같은 요청을 다시 해도 되는 지에 대한 판단 근거가 된다.
    • 그런데 재요청 중간에 다른 곳에서 리소스를 변경하면?
    • 나는 멱등 메서드인 GET을 한번 요청했다. 그 후 다른 사용자가 PUT으로 리소스를 변경한다. 그 후 내가 다시 GET 요청하면 결과값이 다를 것이다.
    • 이것은 멱등과 관계가 없다. 멱등은 외부 요인으로 중간에 리소스가 변경되는 것은 고려하지 않는다.
  • 캐시가능
    • 응답 결과 리소스를 캐시해서 사용해도 되는가?에 대한 것이다.
    • 동일한 요청에 대해 Get, head, post, patch의 결과 리소스는 캐시가 가능하다.
      • Get, head url 캐시 키로 사용하면 되는데
      • Post,patch 바디까지 캐시 키로 사용해야 해서 복잡하다. 그래서 안쓴다.
    • 실제로는 get, head 정도만 캐시로 사용한다.
    • 만약 같은 이미지를 계속 get한다면  브라우져에서 캐시할  있다.(결과값이 같으니까)

HTTP 메서드 별 특징