HTTP Method

구름코딩·2021년 1월 2일
0

HTTP 웹 _ 정리

목록 보기
3/8
  • http Api 설계
  • http 메서드
    • GET, POST, PUT, PATCH, DELETE
  • http 메서드 속성

HTTP API 설계

요구사항

  • 회원 목록 조회

  • 회원 등록

  • 회원 수정

  • 회원 삭제

  • 회원 조회

API URI 설계

먼저 요구사항에 대한 이름 만들기

(CRUD)

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

위와 같은 설계가 좋은 URI 설계일까?

-> 가장 중요한 것은 리소스 식별 !

리소스의 의미는 ?

  • 회원을 등록, 수정, 삭제, 조회 하는 자체가 리소가 아니다
  • 미네랄을 캐라
    • 여기서 리소스는 미네랄이다
      즉, 회원 그 개념 자체가 리소스이다

회원을 등록, 수정, 삭제, 조회 하는것을 모두 배제한다
오직 회원이라는 리소스만 식별하면된다 -> 회원 리소스를 URI에 매핑

따라서 다음과 같이 API URI를 설계

리소스 식별, URI 계층 구조 활용

  • 식별을 위한 id를 이용하자

(CRUD)

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

참고 : 계층 구조상 상위를 컬렉션으로 보고 복수형 단어 사용을 권장한다 (members)

id는 부여했는데 4개의 CRUD끼리 어떻게 구별할지 의문점이 든다

리소스와 행위를 분리

  • URI는 리소스만 식별
  • 리소스와 해당 리소스를 대상으로 하는 행위를 분리
    • 리소스 : 회원
    • 행위 : 등록, 수정, 삭제, 조회
  • 리소스는 명사이고, 행위는 동사이다
  • 행위, 즉 메서드는 어떻게 구분할까? (리소스는 id로 구별)

HTTP 메서드를 통해 위의 역활을 수행한다
http 메서드 : http메시지의 header에 포함되어있다
GET, POST, PUT, PATCH, DELETE

HTTP 메서드(1) - GET, POST

주요 메서드

  • GET : 리소스 조회
  • POST : 요청 데이터 처리, 보통 등록에 사용
  • PUT : 리소스를 대체, 해당 리소스가 없으면 생성
    • 폴더에 파일을 넣을때 있으면 덮어쓰고, 없으면 새로 만드는 것과 같다
  • PATCH : 리소스 부분 변경
  • DELETE : 리소스 삭제

기타 메서드

  • HEAD : GET과 동일하지만 메시지 바디 부분을 제외하고, 상태줄과 헤더만 반환한다
  • OPTIONS : CORS에서 사용한다, 대상 리소스에 대한 통신 가능 옵션을 설명
  • CONNECT : 대상 자원으로 식별되는 서버에 대한 터널을 설정 (거의 사용 x)
  • TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행 (거의 사용 x)

GET

  • 리소스 조회
    • GET /search?q=hello&hl=ko HTTP/1.1
  • 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)를 통해서 전달
  • GET을 사용해서 메시지 바디 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않는다

클라 -> 서버 (메시지 전달)

  • 클라에서 보내는 HTML 메시지
GET /members/100 HTTP/1.1
Host :localhost:8080
(개행)
  • members/100 (json데이터)
{
	"username":"woonsik",
	"age":20"
}

메시지 서버 도착
서버가 메시지를 확인해서 응답데이터를 응답메시지로 만들어서 클라에게 전달

서버 -> 클라 (응답 데이터 전달)

응답 데이터

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 34

{
	"username":"woonsik",
	"age":20"
}

POST

  • 요청 데이터 처리
  • 요청 메시지의 메시지 바이를 통해서 서버로 요청 데이터를 전달
  • 서버는 요청 데이터를 처리
    • 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행
  • 주로 전달된 데이터로 신규 리소스 등록, 변경된 프로세스 처리에 사용

클라 -> 서버 (메시지 전달)

메시지

POST /members HTTP/1.1
Content-Type: application/json

{
	"useranme":"woonsik",
	"age":"20"
}

미리 클라이언트-서버간에 데이터 처리에 대해 약속을 해놓는다

만약 클라이언트가 POST/members에 데이터를 보내면 서버는 전달받은 해당 데이터를 저장 혹은 내부적인 프로세스로 사용하는데 쓰겠다 라는 식이다


신규 리소스 생성

/members -> /members/100 신규 리소스 식별자 생성

{
	"useranme":"woonsik",
	"age":"20"
}

서버 -> 클라이언트 (응답 데이터 전달)

응답 데이터

HTTP/1.1 201(200도 가능) Created
Content-Type: application/json
Content-Length: 34
Location: /members/100

{
	useranme":"woonsik",
	"age":"20"
}

서버는 요청 데이터를 어떻게 처리할까?

POST 정의 : POST 메서드는 대상 리소스가 리소스의 고유한 의미 체계에 따라 요청에 포함된 표현을 처리하도록 요청한다

POST의 기능 예시)

  • HTML 양식에 입력된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공하여 처리한다
    • HTML FORM에 입력한 정보로 회원가입, 주문 등에서 사용
  • 게시판, 뉴스그룹, 메일링 리스트, 블로그, 유사한 기사 그룹에 메시지 게시
    • 게시판 글쓰기, 댓글달기
  • 서버가 아직 식별하지 않은 새 리소스 생성
    • 신규 주문 생성
  • 기존 자원에 데이터 추가
    • 한 문서 끝에 내용 추가

즉, 이 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야한다 -> 정해진 것이 없다

  1. 새 리소스 생성 (등록)
  • 서버에 아직 식별하지 않은 새 리소스를 생성
  1. 요청 데이터 처리
  • 단순히 데이터를 생성하거나 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우
    • 예시) 주문에서 결제완료 -> 배달시작 -> 배달완료 처럼 단순히 값 변경을 넘어서 프로세스의 상태가 변경되는 경우
    • 예시) POST /orders/{orderID}/start_delivery (컨트롤 URI) 리소스만으로 설계를 못하는 경우도 존재
    • 위의 경우 POST의 결과로 새로운 리소스가 생성되지 않을 수 도 있다
  1. 다른 메서드로 처리하기 애매한 경우
  • 예시) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우
  • GET메서드로는 body에 내용물을 넣어도 안받아주는 경우가 많으므로 POST로 처리 (쿼리를 못쓸때의 경우)
  • 애매하면 POST를 사용

HTTP 메서드(2) - PUT, PATCH, DELETE

PUT

  • 리소스를 대체
    • 리소스가 있으면 (완전히)대체 (= 덮어쓰기)
    • 리소스가 없으면 생성
  • 클라이언트가 리소스를 식별
    • 클라이언트가 리소스 위치를 알고 URI를 지정한다
    • POST와 다른점이다 (POST는 해당 리소스를 지정하지 않는다)
PUT /members/100 HTTP/1.1 (100번 리소스를 지정)
Content-Type: application/json

{
	useranme":"woonsik",
	"age":"20"
}

즉 지정한 리소스에 위의 데이터를 주는 것, 따라서 미리 약속이 필요없다

서버에 리소스가 존재한다면, members/100이 이미 있다면 전달하는 데이터로 완전히 대체한다

따라서 기존 데이터에 추가적인 데이터가 있더라도 다 지우고 새로 쓰게 된다. 그러므로 수정개념이 아니라 새롭게 만드는 개념이다

없다면 해당 데이터를 새로 생성

그렇게 결과적으로는 요청한 데이터로 새로만든 리소스를 클라이언트에게 반환 데이터로 전달

PATCH

  • 리소스 부분 변경

위와 같이 PUT이 리소스의 수정에 힘들다 보니 새로 추가된 메소드가 PATCH이다

PATCH의 경우 put과 똑같이 리소스의 URI를 지정하고 데이터를 전달하며, 해당 데이터가 서버의 리소스에도 있다면 변경(업데이트)해주고, 없다면 추가해준다 (기존 리소스의 데이터를 건들지 않는다)

그렇게 변경(수정)된 리소스를 반환 데이터로 클라이언트에게 전달

DELETE

따로 클라에서 메시지를 보낼때 http body의 내용은 없고 리소스의 URI를 지정해서 해당 리소스를 클라이언트에서 지운다

DELETE /members/100 HTTP/1.1 (100번 리소스를 지정)
Content-Type: application/json

HTTP 메서드의 속성

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

안전 Safe

호출해도 리소스를 변경하지 않는다

  • GET

Q. 지속적으로 호출해서 로그같은게 쌓여서 장애가 발생한다면?
A. 안전은 해당 리소스의 안전만을 고려한다. 그외의 부분은 고려하지 않는다

멱등 Idempotent

몇번을 호출해도 결과가 동일하다

  • f(f(x)) == f(x)
  • GET, PUT, DELETE

조회를 몇번해도, 같은 데이터로 계속 덮어 씌어도, 같은 데이터를 계속 지워도 결과는 동일하다

POST의 경우 두번이상 호출하면 같은 행위가 중복해서 발생 할 수 있다

  • 댓글을 계속 쓴다던가, 신규 주문을 계속 생성한다던가 등

왜 멱등 기능이 필요할까?

활용

  • 자동 복구 메커니즘으로 사용된다. 만약 서버가 TIMEOUT등으로 정상적인 응답 메시지를 주지 못했을 때, 클라이언트는 해당 명령(메소드)를 다시 보내도 될지 판단하는 근거가 된다
  • 멱등한 메소드라면 다시 보내도댐, 아니면 안된다

Q. 재요청 하는 중간에 다른곳에서 서버의 리소스를 변경한다면 멱등한 메소드라도 다른 리소스를 변경하게 되는데?
A. 외부 요인은 따지지 않는다. 단지 지금 사용하는 메서드의 관점에서만 따진다

Q. PATCH는 왜 멱등하지 않을까?
A. PATCH는 멱등할 수도 있고, 않할 수도 있다. 만약 이름을 a에서 b로 변경해라 와 같은 경우에는 지속적으로 불려도 결과가 동일하겠지만, 만약 나이가 10세 이하인 경우 특정값을 5 증가시켜라 와 같은 쿼리이면 반복했을때 지속적으로 값이 변경되는 결과를 낳을수 있다

예를 들어서 json데이터가 {"name":"kim"}인 경우는 멱등하겠지만 {"operation":"add", "age":"1"}인 경우에는 나이가 계속 1씩 더해지는 것이므로 멱등하지 않는 것

캐시가능 Cacheable

응답 결과 리소스를 캐시해서 사용해도 되는가

웹을 리롤드 할 경우 이미 다운받은 웹의 구성요소들이 있을 텐데 굳이 다시 다운받지 않고 로컬의 웹브라우저의 캐시메모리에 저장을 할수 있다

캐시가능 (웹브라우저가 해당 요청의 이미지를 저장하고 있을수 있는가 없는가)

  • GET, HEAD, POST, PATCH

실제로는 GET, HEAD 정도만 캐시를 사용한다

POST, PATCH의 경우 본문 내용도 캐시 키(key)로 고려해야하는데 구현이 쉽지 않다

캐시를 하기위해서는 key가 맞아야 value를 가져오는데 POST, PATCH의 경우 http 메시지의 body가 있으므로 해당 내용들까지 key로 고려하기가 쉽지 않다


정리

http api를 설계할때 자원, 리소스를 식별하는 구조로 해야한다. 동사가 아닌 명사(식별자, id)로 구분하고 동사는 http의 메서드를 활용하자

메서드로는 GET, POST, PUT, PATCH, DELETE 등 존재

위 메서들의 특징으로 Safe, Idempotent, Cacheable이 존재한다

해당 메소드를 써도 서버의 리소스가 안전한가?

  • GET, HEAD

해당 메소드를 반복적으로 불러도 서버의 리소스의 결과가 동일한가?

  • GET, PUT, DELETE
  • PATCH의 경우 PUT과 다르게 리소스의 부분을 변경하는 것이므로 항상 동일할것이라고 보장할 수 없다

해당 메소드의 결과를 cache해도 되는가?

  • GET, HEAD
  • PATCH, PUT (http 메시지의 body도 캐시의 key값으로 고려해야되서 구현하기 쉽지않아서 안쓴다)
profile
내꿈은 숲속의잠자는공주

0개의 댓글