강의와 책과 스터디

HTTP.03.HTTP 메서드01

우당탕 오리의 개발모험 2023. 4. 7. 19:02

HTTP 메서드 종류와 특징

HTTP API 설계에서 '리소스'와 '행위'를 분리한다는게 무슨말인가?

'신규 회원을 등록한다'에서 '회원'은 리소스, '등록한다'는 행위다.

예전에는 /members/save 같이 행위(등록한다)를 API에 포함해 설계하길 많이 했다.

하지만 요즘은 API에 /members 같이 '리소스'만 명시한다.

행위에 대한 해결책은 HTTP 메서드로 해결한다

HTTP 메서드 종류 5 & 특징

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE

GET

  • 용도 : 데이터 조회.
    • 1개 데이터 요청 : 유일키(ID)로 1개 데이터 조회 ex) /members/1
    • N개 데이터 요청 : '필터'와 '정렬' 검색조건을 전달하고 조건에 맞는 데이터 목록을 조회
      ex) /members?status=ACTIVE&team=DEV3
  • 요청데이터 : Form-Data, Request-Param, Path-Variable
    • 주의 : Request-Body 는 사용하지 않는다(서버마다 지원하지 않을 때가 있다)

POST

  • 용도 : 신규 데이터 생성 or 애매한 API
  • 신규 데이터 생성 : Client 쪽에서 데이터의 키(ID)를 모르고 리소스를 생성할 때
    일반적인 데이터 생성 대부분. ex) POST /members
  • 키 생성 : 서버에서 키(ID)를 생성한다
  • 요청데이터 : Request-Body

PUT

  • 용도 : 데이터 신규 생성 or 데이터 수정 : 데이터가 없으면 신규 생성하고, 이미 있으면 덮어쓴다
  • 주의 : '덮어쓴다'의 의미 = 기존 데이터 아예 없애고 요청데이터로 다시 저장
  • POST와 차이점 : Client 쪽에서 데이터 키(ID)를 알고있는 상태로 리소스를 생성할 때 사용한다
    주로 file을 저장시 사용. ex) PUT /file/image01.png
  • 키 생성 : Client에서 키(ID)를 생성한다
  • 요청데이터 : Request-Body

PATCH

  • 용도 : 데이터 일부 수정 (일반적으로 생각하는..)
  • PUT과 차이점 : PUT은 데이터 전체를 바꾸는 반면 PATCH는 '일부'만 부분적으로 변경한다
    DB SQL로 치자면... 
    • PUT : delete 후 insert
    • PATCH : update
  • 요청데이터 : Request-Body

DELETE

  • 용도 : 데이터 삭제
  • 요청데이터 : Path-Variable (보통)
    • 주의 : Request-Body 안 씀
  • 주로 데이터의 유일키(ID)를 포함해서 요청한다. ex) DELETE /members/1

POST 메서드의 다양한 역할 (단순히 데이터 생성이 아니다) - 애매하면 POST

주요 용도 : 일반적인 데이터 생성. 요청하는 쪽(Client)에서 데이터의 키(ID)를 모르는 상태에서 데이터 생성 할 때 사용한다

  1. 대부분의 신규 데이터 생성
  2. 데이터 생성이 아니더라도 '프로세스 변경'을 감지해야 하는 API에도 사용한다.
    예) 고객이 호출한 택시가 요청장소에 도착했다
  3. 그 외에는 5개 API에 딱 맞아 떨어지지 않는 API 호출에 사용한다(만능)

PUT 메서드의 큰 2개 특징

Client가 보낸 데이터가 리소스에 없으면 신규 생성, 있으면 수정한다(덮어쓴다)

  1. 신규생성 시 특징 : Client가 키(ID)를 보내준다. 즉 서버에서 키를 생성하지 않는다.
  2. 수정 시 특징 : 리소스의 일부만 update하는 것이 아닌, 아예 기존 데이터 삭제하고 Client가 보낸 데이터로 새로 저장한다 = 덮어쓴다
    ex) Client가 회원상세페이지에서 '연락처'를 수정하고 저장했다 => 해당 회원의 기존 회원정보는 삭제하고, 새로 들어온 회원정보로 이름, 나이, 연락처, 주소 모두 다시 저장한다

PUT과 PATCH 차이점.

PUT은 덮어쓰는 수정을 하고

PATCH는 일부만 수정한다

PUT과 POST 차이점

데이터의 키(ID)를 생성하는 주체가 다르다.

PUT은 Client가 신규 데이터의 키(ID)를 알고 아예 요청API에 담아서 보내주고

POST는 Client는 신규 데이터 키를 모르고 Server에서 키를 만든다

PATCH를 잘 사용하지 않는 이유

주의! 강의내용X. 내가 실무에서 겪은 일과 생각

 

대부분의 데이터 생성 할 때는 서버에서 키를 생성한다 -> 즉, POST 사용

대부분의 데이터 수정 할 때는 일부만 수정한다 -> 즉, PATCH 사용

 

즉, PUT과 PATCH를 둘 다 사용할 일이 많지 않은 것.

근데 실무에서 대부분 PUT이 익숙한지 PUT을 PATCH의 의미로 많이 사용한다.

즉, PUT을 사용하지만 그 용도는 PATCH용도와 동일하게 사용.

나도 굳이 PATCH를 사용하나? 생각했다.

 

하지만, 이번 강의를 듣고 생각이 달라졌다.

오히려 PATCH를 사용하고 PUT을 사용하지 않는게 낫겠다고 생각한다.

그럼 추후 만약 PUT의 용도가 필요 할 때 정확하게 쓸 수 있기 때문이다.

HTTP 메서드의 속성 3가지

  • 안전한가?
  • 멱등한가?
  • 캐시가능한가?

'안전'의 의미?

호출해도 리소스가 변경되지 않는다는 의미.

단, 딱 타겟 그 리소스만 고려해서 변경하지 않으면 '안전'한 것임(그 외 리소스는 논외)

PUT, DELETE가 왜 '멱등'한가? + 멱등의 의미

Idempotent

멱등이란? 같은 요청을 여러번해도 프로세스상 문제가 없다. (데이터의 변화가 없다=프로세스상 문제가 없다)

ex) OK : 회원탈퇴 요청을 여러번 해도 문제없다(해당 회원만 탈퇴처리되는 결과는 바뀌지 않는다)

ex) OK : 리뷰삭제 요청을 여러번 해도 문제없다(그 리뷰만 삭제되는 결과는 바뀌지 않는다)

ex) OK : 10개 파일을 PUT 메서드로 업로드를 여러번 해도 문제없다(결과적으로 10개 파일만 저장된다)

ex) X : 주문 요청을 여러번 하면 안된다(중복 주문이 들어가 버린다)

 

그래서.. 이론적으로 보자면

PUT은 덮어쓰는 요청이므로 Client가 의도한 결과가 나온다.

DELETE도 유일키(ID)로 리소스를 찾아 1개만 삭제하는 것이기 때문에 다른 데이터가 삭제될 일이 없다

 

음... 근데 실무 프로세스에서는 이렇게 단순하지 않음ㅎ

만약 리뷰삭제를 한다면 10포인트를 차감해야한다고 해보자.

뭐.. 개발적으로 방어할 수도 있겠지만, 방어로직이 없다면 리뷰삭제요청을 여러번 한만큼 포인트가 중복해서 차감될 수 있다.

5번 리뷰삭제 버튼을 클릭했을 때 10포인트만 차감되어야 하는데 50포인트가 차감된 결과가 나올 수 있다

이건 아주 단순한 예시지만 하고싶은 말은 실무에서는 DELETE 요청이더라도 내부 프로세스는 복잡할 수 있다는 걸 말하고 싶다.

POST만 '멱등'하지 않은 이유

  • GET, PUT, DELETE : 멱등 O
  • POST : 멱등 X. 우리의 만능 POST는 어떤 프로세스가 있는지 알 수 없다. 여러번 호출했다간 큰일나는 프로세스가 있을지도!
    ex) 결재를 여러번 호출하면 중복결재가 발생한다!, 포인트적립을 여러번 호출하면 중복적립이 발생한다! .... 등등

'멱등'이라는 매커니즘이 필요한 이유

예를들면 '자동 복구 메커니즘'에서 필요하다고 한다.

서버가 비정상 이유로 응답이 안올 때 클라이언트가 같은 요청을 다시 해도 되는지 판단근거로 삼는다

 

아! 글쿠나!!

그럼 HTTP 메서드 설계할 때 진짜 조심해야겠는데?.....라고 생각했지만

사실 멱등 성질이 절대적이지 않은 것 같다.

DELETE라도 멱등하지 않을 때도 있다.

GET이라도 멱등하지 않은 경우 - 멱등의 의미 제한

GET이 멱등하지 않을 때가 있을 것이라고 물어볼것이다.ㅎㅎ

예를들면, 1번데이터를 A가 조회해서 보고있었는데

다른 B가 1번을 수정했어

그리고 다시 A가 1번을 조회했을 때 다른 데이터가 보이겠지?

 

이런 경우에는 GET이 멱등하지 않잖아!

 

멱등은 외부 요인으로 리소스가 변경되는 것은 논외로 한다.

즉, 같은 사용자가 외부의 방해가 없이 오직 그 사용자만 특정 리소스를 요청했을 때 반복해서 요청해도 되냐 마냐로 구분한다.

캐시가능 - 실무에서는 무슨 메서드를 보통 캐시를 구현할까? 그리고 왜일까?🙉

캐시가능은 응답 결과 데이터를 캐시해서 사용해도 되는가 여부를 묻는 것이다.

실제로는 GET, HEAD 정도만 캐시한다.

??? 그러게... 어떤 용도로 캐시하지? 클라이언트 단에 캐시한다는 건가? 

 


이 글은 인프런 김영한 님의 강의 '모든 개발자를 위한 HTTP 웹 기본 지식'를 공부하고 개인적으로 정리한 글입니다.