본문 바로가기
Back-end/기초부터 따라하는 nest.js

시즌 2 #1. 기초부터 따라하는 Nest.js 2 : HTTP 메소드

by hsloth 2024. 5. 8.

 

이전 시간에는 간단하게 서버와 클라이언트에 대해서 다뤄봤습니다.

https://suloth.tistory.com/191

 

시즌 2 #0. 기초부터 따라하는 Nest.js 2 : Orientation

조금 더 디테일하게 따라할 수 있는 Nest.js 튜토리얼 시리즈를 제작해보고자 "기초부터 따라하는 Nest.js 2"를 제작하게 되었습니다. 먼저, 사전 준비를 간단하게 해주셔야 할텐데요. 다음 글들을

suloth.tistory.com

 

 

이번 시간에는 서버 개발자라면 필수적으로 알아야하는 HTTP 메소드에 대해서 알아보도록 합시다.


HTTP가 뭐예요?


 

HTTP는 Hyper Text Transfer Protocol의 약자로 직역하면 "하이퍼텍스트를 전송하는 프로토콜" 이라는 뜻입니다.

프로토콜 = 통신 규약 이라는 뜻이지만, 일단은 그냥 가볍게 통신하는 데이터의 단위라고 생각합시다. HTTP통신은 기본적으로 HTTP메시지라는 것을 주고 받으면서 통신을 하게됩니다. 따라서 HTTP 통신을 한다 -> HTTP 메시지를 주고 받는다. -> 데이터를 주고 받는다.

 

우리가 인터넷에서 하는 대부분의 행동이 HTTP통신을 통해 이루어집니다. 브라우저에서 인터넷 창을 켜고, 검색을 하고, 블로그에 들어가고, 댓글을 다는 등 거의 모든 행동 하나하나가 HTTP통신이라고 생각하면 됩니다.

크롬 브라우저를 켜면 구글 홈페이지가 뜨죠?! 구글 홈페이지가 뜨는 이유는 HTTP통신을 통해 인터넷 상에 존재하는 구글서버에게 "나 구글 홈페이지 들어갈래, 구글 홈페이지 줘" 라고 요청을 보내면 구글 서버가 구글 페이지를 우리한테 응답으로 돌려주는 것입니다.

 

이러한 일련의 과정은 모두 HTTP통신을 통해서 이루어집니다.

컴퓨터가 실제로 구글 서버에게 "구글 홈페이지 줘"라는 말을 구글 서버에 보내서 구글 서버에서 홈페이지를 주는건 아니란 말이죠?!

위의 과정을 조금 더 자세히 적어보면, 아래와 같습니다.

 

위의 그림은 사용자가 브라우저 주소창에 www.google.com을 입력하였을 때 발생하는 일입니다.  

먼저, 사용자가 구글 주소를 주소창에 입력해서 엔터를 누르면 빨간 화살표에 해당하는 동작을 하게 됩니다.

GET이라는 Request(요쳥)가 구글 주소와 함께 구글 서버로 보내지게 되죠. 이를 HTTP Request Message라고 합니다.

이를 해석하면, "www.google.com에 해당하는 리소스(파일)를 얻고싶다고(GET) 요청(Request)."이라는 메시지를 서버에 전달했다고 볼 수 있습니다.

그러면 구글 서버는 이에 대해 사용자에게 응답을 하게 됩니다. 주소창에 구글 주소를 입력하고 일정 시간이 지나면(실제로는 눈깜짝할 사이죠!) 구글 홈페이지가 브라우저 창에 뜨게 됩니다. 이것은 구글 서버가 사용자가 보낸 요청에 응답했기 때문입니다. 해당 과정은 파란 화살표에 해당합니다. 이때, 브라우저가 구글 홈페이지를 띄울 수 있도록 정적 파일(html, css, javascript)을 전달합니다. 브라우저는 해당 파일 내용을 바탕으로 사용자에게 구글 홈페이지를 만들어줍니다.

이것이 HTTP통신의 기본 원리입니다. 요청을 받으면, 서버가 응답하는거죠. 응답은 정상적인 응답일 수도 있고, 문제(에러)가 발생했다는 메시지일 수도 있습니다. 정상적으로 응답했을 때는 구글 홈페이지가 브라우저에 뜨게 되는 거고, 문제가 발생했다는 메시지를 사용자가 받게되면 우리가 웹서핑을 하면서 가장 흔하게 보게 되는 404 Not Found 같은 문구가 브라우저에 뜨게 되는 겁니다.

 

에러가 발생했을 때. 404 Not Found
에러가 발생했을 때. 403 Forbidden

 

 

 


HTTP Message 구조


 

HTTP Message는 크게 두 가지로 나눌 수 있습니다.

바로 Request와 Response입니다.

 

Request Message

Request Message

start line은 다음으로 구성됩니다.

  • HTTP method : 해당 요청이 어떤 동작을 원하는지에 대한 HTTP Method 명시
  • Request target : 어떤 Resource에 대한 요청인지 명시
  • HTTP version : HTTP 프로토콜에도 버전이 있습니다. 어떤 버전의 형식에 맞춘 메시지인지 명시
GET /user HTTP/1.1

 

위를 해석해보면 HTTP 1.1 버전 통신을 하는데, user라는 리소스를 받아오는(GET) 요청이다. 라는 것을 알 수 있습니다.

 

Request headers는 해당 Request에 대한 추가 정보들을 담고 있는 부분입니다.

위의 그림에서는 Host가 google.com이고, (google.com에 요청을 하고 = 구글 서버에 요청을 하고) Content-Type은 json형식이고, Http Request Message의 길이는 213이라는 것을 나타내고 있습니다.

이 밖에도, Accept, Authorization, Origin, Cookie 뿐만 아니라 직접 설정한 부가정보들도 넣을 수 있습니다.

 

blank line은 header와 body를 구분하기 위해 사용됩니다.

 

Request body는 해당 Request Message가 서버로 전송하는 데이터를 담고 있는 부분입니다.

보통은 비어있고, POST, PUT, PATCH 등의 HTTP Method를 사용할 때 포함됩니다.

 

 

Response Message

Response Message

status line은 다음으로 구성됩니다.

  • HTTP version : HTTP 통신 버전.
  • Status Code : 상태 코드(코드 마다 현재 서버의 상태 나타냅니다. 예를들면 200은 정상, 400은 Client 요청 에러, 500은 서버 에러 등이 있습니다)
  • Status Text : 상태 메시지입니다. 상태에 대한 자세한 정보를 메시지로 전달해줍니다. (사용자 정의)
HTTP/1.1 200 OK

 

위를 해석해보면 HTTP 1.1 통신 형식의 메시지이고, 200 상태코드와 OK라는 메시지를 받았다는 것을 알 수 있습니다.

 

Response headers는 Request와 마찬가지로 부가적인 정보가 들어있습니다.

 

blank line은 여기서도 header와 body를 구분하기 위해 존재합니다.

 

Response body는 응답 값이 담겨 있습니다. 예를들어, 구글 홈페이지를 달라고 서버에 요청을 보냈으면, 구글 홈페이지가(정확하게는 html, css, javascript파일이지만) response body에 담겨 있죠.

 


HTTP Method


 

Method = 함수라는 뜻입니다.

HTTP Method는 HTTP Request Message에만 들어가는 항목으로, 요청을 보낼 때 자신이 원하는 행위를 적어서 Request를 보내기 위함입니다.

예를들면, 아까 위에서 구글 홈페이지에 대해서 GET 요청을 보냈었죠? GET은 얻다 라는 뜻이므로, 구글 서버에 나 구글 홈페이지 얻고(GET)싶어 라고 자신의 원하는 행위를 적어서 보낸 것입니다. 따라서 구글 서버는 사용자가 구글 홈페이지를 얻을(GET) 수 있도록 정보를 보내준 것이죠.

 

HTTP Method 종류는 많이 있지만, 대표적으로는 아래 다섯 가지가 있습니다.

GET

서버로부터 리소스를 받을 때 사용하는 메소드입니다. 브라우저 주소창에 url을 입력하고 엔터를 누르면 GET 요청이 해당 url로 보내집니다.

GET 요청은 Request Body에 데이터를 담지 못합니다. 따라서 서버에게 데이터를 보내기 위해서는 Query와 Param(Path)을 사용합니다.

 

Query와 Param

query는 url뒤에다가 ?을 붙이고 key=value 형식으로 데이터를 전달하는 방법을 이야기합니다. 그리고 &를 구분자로 사용합니다.

아래는 구글에 2020년의 "대한민국" 검색 정보를 검색하기 위한 예시입니다. (예시일 뿐입니다. 똑같지 않습니다...)

ex) https://www.google.com?search=대한민국&year=2020 

위를 해석하면, google.com(구글서버)에 "대한민국"을 검색하고 년도는 2020년도로 설정한 정보를 가져와라 라고 해석할 수 있습니다.

 

param은 path라고도 하는데, 그냥 / 을 구분자로 해서 뒤에 계속 값을 입력하는 것입니다.

query에서의 예를 param형식으로 바꾸면 다음과 같습니다.

ex) https://www.google.com/대한민국/2020

위의 예를 보면 알겠지만, "대한민국"이라는 값과 "2020"이라는 값이 명확히 어떤 data를 의미하는지 구분이 잘 가지 않기 때문에 명확히 구분이 가능한 경우에만 쓰는 편입니다(저같은 경우 ㅎㅎ). 혹은 프론트엔드와 백엔드간 상호간의 약속을 잘 정의해야하죠(이해가 잘안된다면 일단 패스 하시길 바랍니다)

 

조금 더 잘 사용하면 이렇게 사용할 수 있습니다.

ex) http://localhost:3000/user/username/suloth

여기서는 suloth가 param이라고 볼 수 있습니다. user의 username이 suloth인 리소스를 가져와라! 라고 요청하는 걸 바로 알 수 있죠.

 

그리고 제일 중요한 것은 query나 param은 get뿐만이 아닌 다른 HTTP Method에서도 사용할 수 있다는 점입니다.

 

POST

서버에 리소스를 생성하기를 요청할 때 사용하는 메소드입니다. 예를들면 블로그에 글을 업로드 하거나, 사진을 업로드, 댓글을 작성하는 행위 등이 모두 POST 메소드를 사용한 요청이라고 볼 수 있습니다.

Post 요청은 리소스를 생성하는 요청이기 때문에 리소스에 대한 정보를 함께 보내야 합니다. 따라서 많은 양의 정보를 필요로 하기 때문에 Request Body에 데이터를 담아서 보냅니다.

 

PATCH

서버에 리소스에 대한 수정을 요청할 때 사용하는 메소드입니다. PUT도 수정을 요청하는 메소드이지만, PUT과 다른 점은 PATCH는 멱등성을 고려하지 않는다는 점입니다.

Patch 요청은 리소스를 수정하는 요청이기 때문에 리소스 정보를 함께 보내야 합니다. 리소스에 대한 수정 정보를 Request Body에 담아서 보냅니다.

 

PUT

서버에 리소스에 대한 수정을 요청할 때 사용하는 메소드입니다. PATCH도 수정을 요청하는 메소드이지만, PUT은 멱등하게 동작합니다.

Put 요청 또한, 리소스를 수정하는 요청이기 때문에 리소스 정보를 함께 보내야 합니다. 리소스에 대한 수정 정보를 Request Body에 담아서 보냅니다.

 

PUT과 PATCH의 차이

Patch는 Put과 달리 리소스에 대한 수정 정보가 일부만 들어가도, 해당 부분만 수정이 되도록 하는 요청입니다.

예를들어, 다음과 같이 user에 name과 age 속성이 있다고 합시다.

// user
{
    name: "suloth",
    age: 17
}

 

그러면 Patch는 age: 15 라는 데이터와 함께 요청을 보내면, age만 15로 바뀌게 됩니다.

// user
{
    name: "suloth",
    age: 15
}

 

 

반면 Put은 리소스에 대한 모든 정보를 담고 있어야 합니다.

age: 15라는 정보만으로 요청을 보낼 수 없습니다. 나머지 속성인 name도 함께 보내주어야 합니다.

따라서 name: "suloth"age: 15 를 모두 담아서 보내야 수정이 됩니다.

 

Patch는 age: 15라는 데이터를 body에 담아서 보내면, 해당 리소스의 age가 15로 바뀌는 것만 보장할 뿐이고 해당 리소스의 다른 속성들에 대해서는 신경쓰지 않습니다.

따라서, 리소스의 처음 상태인 { name: "suloth", age: 17 } 에서 Patch 메소드와 함께 { age: 15 } 를 요청하면, 해당 유저가 { name: "suloth", age: 15 } 인 상태가 될 것이라고 생각할 수 있습니다.

하지만, 현실은 그렇지 않습니다. 서버에는 수많은 요청들이 들어올 테고, 그 중에는 해당 유저에 대한 수정 요청이 수 십, 수 백, 수 천건이 있을 수 있습니다. 그리고 그 중에는 name을 변경하는 요청이 있을 수도 있습니다. 따라서 PATCH 메소드를 사용하면 유저의 name이 "suloth"인 것을 보장할 수 없습니다.

 

반면에 Put은 리소스에 대한 모든 정보를 함께 넘겨주기 때문에 해당 리소스에 대한 멱등성을 보장할 수 있습니다.

즉, 멱등성이란 내가 HTTP 요청을 보냄으로서 예상하는 리소스의 상태와 실제 리소스의 상태가 동일한 지의 여부라고 생각할 수 있습니다.

(일단은 이렇게 생각합시다 ㅎㅎ... 정확히는 같은 요청을 수차례 반복해도 결과를 변형시키지 않는 작업을 말합니다)

 

이야기가 길었습니다. 위를 종합해보면,

단순히 내가 "age를 15로 바꿔줘" 라고 요청한 것만으로는 "그러면 유저의 name은 suloth고 age는 15가 됐겠지?" 라고 확신할 수 없다는 뜻입니다.

위를 확신하기 위해서는 "name을 suloth로 하고, age를 15로 바꿔줘" 라고 요청을 보내야, 그때야 비로소 유저의 name은 suloth고 age는 15가 됐다고 확신할 수 있다는 것입니다.

 

DELETE

서버에 리소스에 대한 삭제 요청을 할 때 사용하는 메소드입니다. 글 삭제, 댓글 삭제 등의 기능을 요청할 때 DELETE 메소드를 사용한다고 보면 됩니다.

Delete는 리소스에 대한 식별자 정보(ex. id)만 존재하면 되기 때문에 별도로 Request Body가 필요하지 않습니다. 따라서 Request Body에 데이터를 담지 못합니다.

 

 

 


 

우리가 서버 개발을 하면서 가장 많이 사용할 메소드들이 위의 5가지입니다. (어쩌면 위의 메소드들만 사용할지도 모릅니다)

 

간단하게 말하면 서버 개발은, 서버로 HTTP Request가 들어오면, Request Message에 들어있는 url경로와 Method에 따른 동작을 미리 함수로 구현해놓고 해당 요청이 들어오면 함수가 실행되게끔 프로그래밍하는 것입니다.

 

추가적으로, HTTP Method는 "약속"입니다. GET 요청이 서버로 들어오면, 리소스 정보를 넘겨주고, DELETE 요청이 들어오면 리소스를 삭제해주는 로직을 작성하도록 서로 맺은 "약속"입니다.

따라서, GET요청이 들어왔는데 백엔드 개발자가 리소스를 지워버리는 로직을 작성할 수도 있습니다.

기본적으로, 개발에 대한 모든 것은 "약속"이라는 것을 알고 이 점을 유의하면 될 것 같습니다. 약속은 악의적으로 깰수도 있으니까요.

 

 

이상으로 HTTP Method에 대한 포스팅을 마치겠습니다. 궁금한게 있으시다면 댓글 남겨주세요!