정적 웹 서버의 Response

Node.js의 HTTP 모듈을 사용해서 웹 서버를 구현합니다. 라우팅이라는 개념과 웹 서버의 HTTP 응답에 대해서 알아봅니다.
웹 서버, 라우팅, HTTP Response


웹 서버

웹 서버의 구조웹 서버의 구조

클라이언트(웹 브라우저, 스마트폰 앱 등)가 웹 서버와 TCP/IP 연결을 맺고 HTTP 프로토콜을 따라 Request를 보내면, 웹 서버는 적절한 Reponse를 보내주고 연결을 끊습니다. Node.js의 http 모듈을 이용해서 기본적인 웹 서버 프로그램을 작성해 보겠습니다.
http 모듈에 어떤 클래스와 메소드, 속성이 있는지 속속들이 알 필요는 없습니다. HTTP의 이론적인 배경을 생각해보면서 그 내용이 어떻게 추상화 되었을지를 생각하면 처음 접하는 모듈에 금방 익숙해질 수 있습니다. Node.js의 http 모듈은 결국 HTTP 프로토콜와 관련된 기능을 구현하기 위해 만들어진 것이기 때문입니다. 추후 다른 플랫폼에서 다른 라이브러리를 사용하더라도 이러한 배경을 생각하면 새로운 API 쉽게 익숙해질 수 있습니다.

Node.js http 모듈 API
Node.js https 모듈 API

server-hello.js

const http = require('http'); // HTTP 관련 내장 모듈

// 새 요청이 생성될 경우의 핸들러를 넘기며 서버 객체 생성
http.createServer((req,res) => {
    console.log(123);

  res.end('Benzen Workshop');

}).listen(5555); // 서버 소켓을 5555번 포트에 바인딩

/**
PC에 바인딩된 공인/사설 아이피나 아래와 같은 특수 아이피로 접속 가능
http://localhost:5555
http://0.0.0.0:5555
http://127.0.0.1:5555
**/

console.log("server-hello HTTP server running in 5555");

서버 프로그램을 강제로 종료시키려면 셸에서 Crtl+C 를 누르세요.

라우팅

라우팅라우팅

웹 서버에서 Request에 대한 처리는 라우팅에서 시작됩니다. 라우팅은 Request Method와 URL을 기반으로 코드를 분기하는 것을 의미합니다. 예를 들어 웹 브라우저에서 메인 페이지를 요청하면, 서버에서는 메인 페이지를 응답하는 코드가 실행되어야 하고, 게시판에 글쓰기를 요청하면, 게시판 글을 저장하고 또 저장 완료를 응답하는 코드가 실행되어야합니다.

위의 server-hello.js 코드에 라우팅이 없는 것처럼, 서버를 어떻게 설계 할 지는 개발자 마음에 달렸습니다. 하지만 일반적으로 웹서버는 Request URL에서 host와 querystring을 제외한 URL path와 Method를 기반으로 라우팅합니다.

server-static.js

const http = require('http');
const fs = require('fs');
const path = require('path');

// 서버 실행 전에 정적인 파일들을 메모리에 로드함
var htmls = {
  index: fs.readFileSync('./index.html'),
  photo: fs.readFileSync('./photo.html')
};

http.createServer((req, res) => {

    var route = req.method + " " + req.url;

    // / 라우팅
    if(route == "GET /"){
      res.statusCode = 200;
      res.setHeader("Content-type", "text/html; charset=utf-8");
      res.write(htmls.index);
      res.end();

    // /photo 라우팅
    } else if(route == "GET /photo"){
      res.statusCode = 200;
      res.setHeader("Content-type", "text/html; charset=utf-8");
      res.write(htmls.photo);
      res.end();

    // URL로 라우팅, 404 처리
    } else {
      // __dirname 폴더에서 파일을 찾아봄
      var fileName = path.join(__dirname, req.url);

      fs.readFile(fileName, (err, data) => {
        if(err){
          res.statusCode = 404;
          res.end("Not Found");

        } else {
          res.write(data);
          res.end();
        }
      });
    }

}).listen(5555);

console.log("server-static HTTP server running in 5555");

위의 웹 서버들은 정해진 정적인 데이터만을 응답해주고 있습니다. 또한 뷰(html)의 재사용성이 부족하기에 유지보수 및 확장에 불리합니다. 실상 위에서 사용한 http 모듈은 저수준 모듈이기 때문에 생산성 있게 웹 서버를 작성하는 데 적합하지는 않습니다. 다음 챕터에서는 http 모듈로 동적인 데이터를 응답하는 웹 서버를 만들어보면서, 고수준으로 추상화된 웹 서버 프레임워크 대한 필요성을 느껴보도록 하겠습니다.

목차
4. 웹 백엔드
5. 데이터베이스
저자

김동욱

개발 경력 약 10년, 전문 분야는 웹 및 각종 응용 소프트웨어 플랫폼입니다. Codeflow를 운영하고 있습니다.

2018년 07월 30일 업데이트

지원되지 않는 웹 브라우저거나 예기치 않은 오류가 발생했습니다.