[Application Layer] HTTP - Method

JUJU·2024년 3월 9일
0

Network

목록 보기
7/21

✏️ HTTP API

단어 사전 API를 만들어보자.
필요한 기능은 다음과 같다.

  1. 단어 목록 조회
  2. 단어 조회
  3. 단어 등록
  4. 단어 수정
  5. 단어 삭제

여기서 리소스는 "단어"이다.
URI API는 "단어"만 식별하도록 설계해야한다.

나쁜 URI 설계 예시

1. 단어 목록 조회: /read-words-list
2. 단어 조회: /read-word-by-id
3. 단어 등록: /create-word
4. 단어 수정: /edit-word
5. 단어 삭제: /delete-word

위의 URI는 리소스만 식별하는 것이 아니라, 리소스 + 행위까지 식별하고 있다.

좋은 URI 설계 예시

1. 단어 목록 조회: /words
2. 단어 조회: /words/{id}
3. 단어 등록: /words/{id}
4. 단어 수정: /words/{id}
5. 단어 삭제: /words/{id}

위의 URI는 리소스인 단어만 식별하고 있다.
조회, 등록, 수정, 삭제 등의 행위는 HTTP Method로 구분하면 된다.


HTTP의 주요 메소드

  • GET: 리소스 조회
  • HEAD: 리소스 조회(Response Body가 비어서 옴)
  • POST: 리소스 처리(주로 등록할 때 사용)
  • PUT: 리소스 대체(없으면 생성)
  • PATCH: 리소스 부분 변경
  • DELETE: 리소스 삭제



✏️ GET

GET Method는 리소스를 조회할 때 사용한다.
정적 데이터 조회: 리소스 경로 사용
동적 데이터 조회: 쿼리 파라미터를 통해서 조회하고자 하는 리소스를 서버에 전달한다.

Request 메시지

GET /words/1020 HTTP/1.1
Host: localhost:8080

Response 메시지

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 35<br>
{
	"word": "Hello",
    "meaning": "안녕하세요"
}



✏️ POST

POST Method는 요청한 리소스를 처리한다.
Request Body를 통해서 서버로 데이터를 전달한다.
전달받은 데이터는 주로 신규 리소스 등록, 프로세스 처리에 사용한다.

Request 메시지

POST /words HTTP/1.1
Content-Type: application/json
{
	"word": "Hello",
    "meaning": "안녕하세요"
}

Response 메시지

HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 35
Location: /words/1020
{
	"word": "Hello",
    "meaning": "안녕하세요"
}

여기서 주목해야할 점은, Request 메시지에서 /words 라는 URI를 썼다는 것이다.
새로운 단어를 등록하기 위해서 POST Method를 사용했지만, 어떤 Path에 넣을 것인지는 지정하지 않았다.

서버는 자동으로 /words/1020 이라는 새로운 식별자를 생성해서 Response 메시지로 Client에게 전달했다.

POST Method를 사용해서 리소스를 처리한다!

중요한 것은, 리소스를 어떻게 처리할 것인지 서버측에서 지정해주어야 한다는 것이다.

POST는 만능이다.

HTTP Method를 사용해서 API를 제작할 때 애매한 부분이 있다면 POST를 사용하자.



✏️ PUT

PUT Method는 요청한 리소스를 대체한다.
요청한 리소스가 없다면 새로 생성한다.

⚠️ POST와의 차이점: PUT은 Client가 리소스의 위치를 알고 있어야 한다.

Request 메시지

PUT /words/1020 HTTP/1.1
Content-Type: application/json
{
	"word": "Hello",
    "meaning": "안녕하세요"
}

신규 리소스 생성됨

/words/1020
{
	"word": "Hello",
    "meaning": "안녕하세요"
}

⚠️ PUT Method는 리소스를 "완전히" 대체한다.

ex) 요청 메시지로 다음과 같이 보내면

{
	"meaning": "안녕"
}

/words/1020에 있는 리소스에서 "word": "Hello"는 없어지고 "meaning": "안녕"만 바뀐다.

{
    "meaning": "안녕"
}

개발자가 의도한 것은 이게 아닐 것이다.
리소스의 일부분만 변경하고 싶다면 어떻게 해야할까?




✏️ PATCH

PATCH Method를 사용하면 리소스의 일부만을 변경할 수 있다.

현재 /words/1020에 존재하는 리소스:

{
	"word": "Hello",
    "meaning": "안녕하세요"
}

Request 메시지

PATCH /words/1020 HTTP/1.1
Content-Type: application/json
{
    "meaning": "안녕"
}

위의 Request 메시지에는 words 필드가 존재하지 않는다.
PATCH Method를 사용하면 words 필드는 바뀌지 않고, meaning 필드만 "안녕"으로 변경된다.


변경된 /words/1020 리소스:

{
	"word": "Hello",
    "meaning": "안녕"
}



✏️ GET/POST + HTML FORM

HTML FORM을 사용해서 데이터를 전송할 수 있다.
HTML FORM을 통한 데이터 전송은 GETPOST만 지원한다.

■ GET FORM

GET Method에 대해서 공부할 때, 정적 데이터는 리소스 경로를 사용해서 조회하고 동적 데이터는 쿼리 파라미터를 사용해서 조회한다고 학습했다.

HTML FORM을 사용하면 입력한 정보를 바탕으로 쿼리 파라미터를 작성해서 요청을 자동으로 생성해준다.

<form action = "/words" method="get">
  	<input type = "text" name = "word">
  	<input type = "text" name = "meaning">
	<button type = "submit">전송</button>
</form>

word에 hello
meaning에 안녕하세요
입력한 후에 전송버튼 누름


생성된 HTTP request message

GET /words?word=hello&meaning=안녕하세요 HTTP/1.1
Host: localhost:8080

word=hello&meaning=안녕하세요 쿼리 파라미터를 자동으로 생성했다.


■ POST FORM

GET FORM은 입력한 정보를 쿼리 파라미터로 작성해줬다면, POST FORM은 입력한 정보를 Body에 넣어준다.

<form action = "/save" method="post">
  	<input type = "text" name = "word">
  	<input type = "text" name = "meaning">
	<button type = "submit">전송</button>
</form>

word에 hello
meaning에 안녕하세요
입력한 후에 전송버튼 누름


생성된 HTTP request message

POST /save HTTP/1.1
Host: localHost:8080
Content-Type: application/x-www-form-urlencoded

word=hello&meaning=안녕하세요

Content-Type: application/x-www-form-urlencoded을 사용한다.
바이너리 데이터를 전송하는 경우 Content-Type: multipart/form-data을 사용한다.




✏️ HTTP Method의 속성

HTTP Method 각각은 서로 다른 속성을 가지고 있다.

Methodsafe 속성idempotent 속성cacheable 속성
GETOOO
POSTXXO
PUTXOX
PATCHXXO
DELETEXOX

■ safe

Safe Method
== 리소스를 변경하지 않는 Method

ex) GET은 리소스를 조회만 할 뿐 변경하지 않는다.
POST, PUT, PATCH, DELETE는 모두 리소스를 변경하는 Method이다.


■ idempotent(멱등)

idempotent Method
== 요청 횟수에 상관없이 결과가 같은 Method
한 번 호출하든 n번 호출하든 결과가 같다.

ex) request1: POST로 단어 "Book" 전달
➜ 새로운 단어로 처리

request2: POST로 단어 "BOOK" 전달
➜ 이미 있으므로 다르게 처리됨

∴ POST는 idempotent Method가 아니다.


■ cacheable

cacheable Method
== 응답 결과 리소스를 캐시해도 되는 Method




✏️ 리소스의 종류

리소스의 타입을 명확하게 알기 위해서 다음과 같은 4가지 방식으로 리소스를 구분한다.

1. document

: 단일 개념(파일 하나, 객체 인스턴스)
ex) /words/1020


2. collection & Store

POST Method로도 리소스 등록을 할 수 있고, PUT Method로도 리소스 등록을 할 수 있다.

POST는 서버가 리소스의 URI를 관리하고,
PUT은 클라이언트가 리소스의 URI를 관리한다.

서버가 관리하는 리소스 디렉토리를 Collection이라 하고,
클라이언트가 관리하는 리소스 저장소를 Store라 한다.


3. Controller

명사만 가지고 API를 설계하기 어려울 때가 있다.

예를 들어, HTML FORM을 사용하여 단어 사전 API를 설계해보자.
HTML FORM은 GET과 POST만 지원한다.

  1. 단어 목록 조회: /words
  2. 단어 조회: /words/{id}
  3. 단어 등록: /words/{id}
  4. 단어 수정: /words/{id}
  5. 단어 삭제: /words/{id}

Json을 사용하면 조회, 등록, 수정, 삭제를 각각 GET, POST, PATCH, DELETE에 대응시키면 되겠지만, HTML FORM은 GET과 POST만 지원한다.

이러한 제약을 해결하기 위해 "동사" 경로를 사용한다.

  1. 단어 목록 조회: /words
  2. 단어 조회: /words/{id}
  3. 단어 등록: /words/new
  4. 단어 수정: /words/{id}/edit
  5. 단어 삭제: /words/{id}/delete

이러한 URI를 Control URI라고 부른다.




REFERENCE

개발자를 위한 HTTP - 김영한 개발자님

profile
개발자 지망생

0개의 댓글

관련 채용 정보