HTTP라는 프로토콜은 그 이름(Hypertext Transfer Protocol)에 맞게 하이퍼미디어 문서 전송을 위해 웹 브라우저와 웹 서버 사이의 통신을 위해 설계되었지만, 연결을 열고 - 요청을 보낸 뒤 - 응답을 대기하는 고전적인 클라이언트-서버 모델이 필요한 곳이라면 웹 문서 전송이 아닌 다른 목적을 위해서도 사용할 수 있다. 이런 곳에서는 백엔드 레이어를 구현할 때 메소드(method)
개념을 생각하게 된다. 클라이언트에게 동일한 URL에 대해 생성/조회/삭제 등의 동작을 제공하는 게 명료하기 때문이다. 메소드는 HTTP 요청에서 사용하며, 클라이언트가 웹서버에게 요청의 목적이나 종류를 알리는 수단으로서 사용한다. HTTP 메소드에는 종류가 참 많은데도 불구하고 나는 GET/POST/PATCH/PUT/DELETE
정도만 사용하고, 알고 있었던 것 같아 한 번 정리해보고자 한다.
HTTP 메소드
HTTP의 요청에서 URL, 헤더, body와 함께 중요한 구성 요소다. 위에서 말했듯 자원(URL)에 대한 행위(verb)
를 명시하기 위해 사용된다. 조회, 전송, 삭제 등의 행위에 따라 여러 종류의 메소드가 존재한다.
GET
GET /news HTTP/1.1
리소스의 표시를 요청한다. URL에 웹 브라우저로 접속하는 것이 대표적인 GET 요청의 예다. 게시글 목록, 주소록 등을 불러오는 것처럼, 데이터를 받아오는 맥락의 HTTP 요청은 통상적으로 GET을 사용한다. 대부분의 경우 GET 요청에는 body가 없다.
POST
POST /post HTTP/1.1
리소스에 데이터를 전송한다. 새로운 게시글을 작성하거나, 회원가입을 하는 등 새로운 데이터를 서버에 등록하기 위해 일반적으로 POST를 사용한다.
PUT
PUT /meal/2018/12/25 HTTP/1.1
POST와 동일하게, 리소스에 데이터를 전송한다. '생성하되, 이미 존재한다면 변경한다'라는 논리가 깔려 있는 것이 한 가지 다른 점이다. 사용자의 설정 데이터 적용이나, 날짜별 급식 정보 업로드처럼 POST와 PATCH를 구분짓기 애매하거나 클라이언트 레벨에서 생성과 수정을 따로 구현하기 귀찮아하는 기능에서 종종 사용했던 것 같다.
PATCH
PATCH /post/9e15c13aed1c48b5 HTTP/1.1
리소스의 특정 부분을 수정하는 데에 쓰인다. 게시글 수정이나 닉네임, 자기소개 변경과 같이 update 개념의 기능에서 자주 쓰인다.
DELETE
DELETE /me/profile-picture HTTP/1.1
리소스를 삭제한다. 친구 삭제나 프로필 사진 제거와 같은 기능에서 쓰인다.
HEAD
HEAD /dumps/log/1540993830.csv HTTP/1.1
리소스를 GET 메소드로 요청하는 경우에 어떤 헤더들이 반환되는지를 요청한다. 큰 용량의 리소스를 다운로드 받을지 말지 결정하기 위해서 Content-Length
를 알아내거나, 응답에 영향을 줄 수 있는 헤더 목록을 조회하기 위해 Vary
헤더를 얻어오는 용도 등으로 사용할 수 있다. HEAD 메소드의 요청에 대한 응답은 body를 가질 수 없고, 만약 가지더라도 무시된다.
OPTIONS
OPTIONS * HTTP/1.1
자원에 대한 통신 옵션을 요청하기 위해 사용된다. 웹 클라이언트의 Axios 모듈에서 Access-Control-Allow-Origin
등과 같은 CORS 정보를 얻어내는 것이 한가지 예다. 서버 전체를 나타내기 위해 asterisk(*)
를 사용하기도 한다.
클라이언트 사이드 렌더링과 HTTP API 기반의 웹 서비스가 활발히 만들어지고 있는 요즘에는 HEAD, OPTIONS와 같은 특별한 것들을 제외한 메소드들은 어떤 용도로 사용되어야 하는지에 대한 정리가 사실상 proposal 수준으로 받아들여지고 있는 것 같다. 따라서 '조회에는 무조건 GET을 써야 한다'라기보단 '조회와 비슷한 맥락의 기능에는 GET을 쓰는 게 좋다' 정도로 생각하면 될 것 같다. 내 경우에도 '목록 조회' 동작임에도 불구하고 요청 데이터의 양이 많아서 JSON body를 사용하도록 하기 위해 POST로 API를 구성할 때가 종종 있었다. ElasticSearch나 Druid는 GET에도 body를 포함시킬 수 있는데, 이게 웬만한 웹 프레임워크들에서도 지원된다면 참 좋겠다.