4. Node HTTP 모듈 알아보기

hoonnote·2020년 9월 29일
0

express-101

목록 보기
1/1

Express에 대해서 본격적으로 들어가기 전에, 우선 Express가 만들어지기 전에는 Node로 어떻게 서버를 만들었는지 알아봅시다.

HTTP Module

1. HTTP Module이란?

HTTP Module은 Node.js 에서 기본적으로 제공해주는 모듈로써,
npm을 활용해 설치할 필요 없이 바로 사용이 가능합니다.

HTTP 모듈은 서버를 만들어주는 createServer 메소드를 갖고 있고,
메소드에는 1개의 callback 함수를 argument로 받아오는데요,
콜백 함수는 각각 requestresponse Object를 입력해줍니다.

createServer((<request객체>, <response객체>) => {
  // 이 안에서 코드를 작성해주면 됩니다 
})

callback function에 전달해주는 response 와 request 는 컨벤션에 따라 reqres로 사용을 합니다.
이미 npm modulerequestresponse 모듈들이 있기 때문이죠!

2. http 모듈을 이용해 서버를 생성해봅시다.

const http = require('http');

const server = http.createServer((req, res) => {
  // 이 안에서 코드를 작성해주면 됩니다 
})

createServer안에 전달해준 callback 함수에 입력된 req와 res는 각각의 역할이 있는데요,
req는 HTTP Request를 표현해 줍니다.

HTTP Request는 통신을 요청한 사람의 정보가 담겨있습니다:

  1. 누가 요청을 했는지 (IP주소)
  2. 무슨 웹 브라우저에서 요청을 했는지
  3. 어떤 페이지로 접근요청을 했는지 ..
    등등 다양한 정보가 있습니다

이렇게 서버를 만들어보았는데요, 사실 서버를 제대로 작동하게 하기 위해서는 서버가 동작할 포트를 지정해주어야 합니다.

3. 서버를 동작시켜 봅시다

우리가 위에 만들었던 createServerlisten 메소드를 담은 object를 리턴해줍니다.
그리고 listen은 1개의 argument를 받는데요,
그 argument는 우리 서버가 동작할 서버의 포트 주소를 받습니다.

server.listen(<PORT 주소>)

Port의 숫자는 1000보다 큰 숫자라면 아무 숫자로 지정해도 상관 없습니다.
그러고 우리가 요청받은 request object를 한번 출력보도록 할까요?

const http = require("http");

const server = http.createServer((req, res) => {
  console.log(req)
});

server.listen(3000);

이렇게 저장을 해도 아무일도 일어나지 않습니다.

그 이유를 간단하게 설명하자면,

  1. createServer() 메소드는, http request가 발생하면 createServer안에 있던 callback 함수를 실행시킵니다.
  2. 하지만 콜백 함수는 우리가 최 하단에 입력해주었던 server.listen(3000) 포트의 주소로 요청이 들어올때만 실행이 되는거죠
  3. 따라서 createServer를 이용해서 만들어진 서버는 3000이란 주소의 포트에 들어오는 모든 요청들을 지켜보며 요청이 들어오는 경우에만 동작을 하는거죠.

그렇다면, 도대체 왜 console.log(req)를 한 req object가 출력되지 않은걸까요?

그 이유는, 우리가 아직 Port 주소가 3000인 서버에 아무 요청도 보내지 않았기 때문입니다!

그러면 새로운 인터넷 창을 열어서 아래의 주소를 입력하여 우리가 생성한 포트 주소에 해당하는 서버로 접근해봅시다

웹페이지에는 아무 정보도 나타나지 않지만, 우리의 콘솔창에는 뭔가 어마어마한게 나타났죠.

...
headers: {
host: 'localhost:3000',
connection: 'keep-alive',  
 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,_/_;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'none',  
 'sec-fetch-mode': 'navigate',  
 'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',  
 'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en,ko-KR;q=0.9,ko;q=0.8',
cookie: 'username-localhost-8888="2|1:0|10:1601268253|23:username-localhost-8888|44:NDVlNDUyOGQ5MzgxNDY1Njg5OGZmZDg4NTAzOTkyYmY=|b1bef428db1be91671b7b6e473347ba0b7bbcb3de2d8cdd7e2c9934e8d1ad23e"; \_xsrf=2|2d166d16|0c864c549731f26bd9ad502c3fffced0|1601268253'
},
...

이런식으로, 우리의 서버가 전달받은 요청 request 에 대한 모든 정보들을 출력해서 볼 수 있습니다.

그리고 우리가 localhost:3000에 접근을 하였지만 페이지가 아무것도 출력하지 않는데요,
그 이유는 웹 브라우저가 보내준 요청 (HTTP request)를 통해 서버와 인터넷 브라우저가 연결은 되었지만, 서버는 아무런 정보도 돌려주지 않아 웹 브라우저가 하염없이 기다리고 있는 상태이기 때문입니다.

HTTP 통신의 특성상, 서버가 요청을 받게되면 해당 요청에 대한 응답을 해주어야만 통신이 끝나게 되는 이유이기도 하죠.

4. 요청에 대한 응답을 해봅시다

const server = http.createServer((req, res) => {
  console.log(req);
});

createServer()가 받아온 callback 함수에 있는 res는 우리가 받은 - 그리고 아까 출력 시켰던 - req에 대한 응답을 할 수 있는 방법입니다.

res 를 사용해서 HTTP message를 구성해 다시 웹 브라우저에게 전달해주어야 하는데요,
Http Message는 아래와 같이 구성되어 있습니다.

  1. Start-line : Node.js가 알아서 처리를 해줍니다
  2. Header : 우리가 직접 설정을 해주어야 하구요
  3. Body : 웹에게 전달해줄 내용입니다.

1번에 해당하는 start-line은 노드가 자동으로 처리를 해주기 때문에 우리가 신경쓸 필요는 없겠죠.

그럼 header와 body가 도대체 뭔지 알아봅시다.

Header 란?
Response 객체의 header는 우리가 전달해 주는 데이터에 대한 정보를 담아 전달해줍니다.
res.writeHead() 를 사용하여 설정해 줄 수 있으며,
writeHead(<statusCode>, <mime-type>)는 두개의 argument를 받아옵니다

  1. 통신 상태를 나타내는 Status Code와
  2. 전송된 문서의 타입을 알려주기 위한 Mime Type을 전달받습니다.

우리가 전달해줄 수 있는 status code는 아래와 같습니다

1 1xx (조건부 응답)
2 2xx (성공)
3 3xx (리다이렉션 완료)
4 4xx (요청 오류)
5 5xx (서버 오류)

mime-type 은 type/subtype 의 구조로 생성됩니다.

text/plain
text/html
image/jpeg
image/png
audio/mpeg
audio/ogg
audio/*
video/mp4
application/octet-stream

등등 다양한 타입들이 있습니다.

Mime Type이 사용되는 이유는, 웹에서 파일의 확장자는 별 의미가 없습니다. 그러므로, 각 문서와 함께 올바른 MIME 타입을 전송하도록, 서버가 정확히 설정하는 것이 중요하기 때문입니다.

따라서 아래와 같이 코드를 작성해 헤더를 생성시켜줍시다

res.writeHead(200, {"content-type": "text/html"});

이 코드는, 200의 statusCode와 "content-type": "text/html"의 Mime-type을 전송할거란 설명을 해주는 헤더를 생성해줍니다.

헤더가 완성이 되었으니, 전달시켜줄 본문인 Body 부분을 작성해봅시다

res.write("<h1>Hello from Node HTTP</h1>");

그러고, 모든 통신이 완료되었음을 표현해주기 위해서 res.end()를 사용해줍시다

const http = require("http");

const server = http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/html" });
  res.write("<h1>Hello from Node HTTP</h1>");
  res.end()
});

server.listen(3000);

그러면 다시 웹 브라우저를 열어서 localhost:3000을 입력하면 어떤 결과가 나올까요?
한번 확인해 봅시다.

우리가 body에 입력한 그대로 HTML이 출력되는 걸 볼 수 있습니다.

이렇게 우리가 만든 서버를 이용해 의미있는 데이터를 전달해보았습니다.

HTTP 모듈 안에는 훨씬 많은 기능들이 있지만, 가장 기본적인 서버 구성을 위해 여기까지만 알아보도록 하겠습니다.

profile
개발하는 마케터

0개의 댓글