Node.js 예시 프로젝트

초 기초 Nodejs프로젝트를 만들어보자.(poiemaweb 참고)

example
└──server.js
  • Node.js에 기본 포함되어 있는 http 모듈을 로드한다.
var http = require('http');
  • http 모듈의 createServer 메서드를 호출

  • http.createServer([requestListener])는 http.Server의 새로운 인스턴스를 반환한다. (server변수)

  • 서버가 특정한동작을 수행하게 하려면 콜백함수를 지정해야 한다.

  • createServer에 인자로 들어가는 함수는 request이벤트(서버요청)가 발생했을때 자동으로 호출될 콜백함수이다.

var server = http.createServer(function(request, response){
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
});

server.listen(3000);
  • 요청이벤트(request)이 올 때마다 response.writeHead()함수를 사용해서 HTTP status 200과 content-type을 응답 헤더로보낸다.
response.writeHead(200, {"Content-Type": "text/plain"});
  • http.Server의 인스턴스 server의 메서드 listen을 호출하여 접속대기를 시작한다.
server.listen(3000);

여기까지의 최종코드

//server.js

// Node.js에 기본 포함되어 있는 http 모듈을 로드한다.
var http = require('http');

// http 모듈의 createServer 메서드를 호출
// http.Server의 새로운 인스턴스를 반환한다. (server변수)
// 서버가 특정한동작을 수행하게 하려면 콜백함수를 지정해야 한다.
// createServer에 인자로 들어가는 함수는 requiest이벤트(서버요청)가 발생했을때 자동으로 호출될 콜백함수이다.
var server = http.createServer(function(request, response){

  //요청(request)이 올 때마다 response.writeHead()함수를 사용해서 HTTP status 200과 content-type을 응답 헤더로보낸다.
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
});

//http.Server의 인스턴스 server의 메서드 listen을 호출하여 접속대기를 시작한다.
server.listen(3000);

이것을 모듈화 시킬다. ( requestListener를 만든다고 생각하면 된다.)

var http = require('http');

function start(){
  function onRequest(request, response){
    console.log("Request received");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  var server = http.createServer(onRequest);
  server.listen(3000);

  console.log("Server has started.");
}

//모듈화시킨 함수를 exports
exports.start = start;

index.js 를 생성해서 모듈화 시킨 server.js를 불러온다.

//index.js
var server = require("./server");

server.start();

HTTP 요청(비동기적 이벤트)이 발생하면 callback(onRequest)이 호출된다. 이때 request, response가 callback 함수 onRequest에 전달된다. 요청에 대한 처리를 callback에서 처리한다.

Request received가 두번뜨는건 favicon때문이다.

라우팅

요청(request) url과 GET/POST 파라미터에 따라 서버의 할일이 정해지는데, 서버의 할일을 수행하는 함수를 request handler라 한다. router의 역할은 path를 기반으로한 요청을 받아 request handler를 매핑하는것 이다.

라우터를 만들기 위해 url모듈을 사용해 url를 분류하고 파라미터를 취득할수 있어야 한다.

// url & querystring modules

                        url.parse(string).query
                                        |
          url.parse(string).pathname    |
                        |               |
                        |               |
                      ----- -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
        querystring.parse(string)["foo"]    |
                                            |
                querystring.parse(string)["hello"]
  • server.js에 url 모듈 사용하였다.
var http = require("http");
var url = require("url");

function start(){
  function onRequest(request, response){
    var pathname = url.parse(request.url).pathname;
    console.log("Request " + pathname + " received");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  var server = http.createServer(onRequest);
  server.listen(3000);

  console.log("Server has started.");
}

exports.start = start;

router.js를 만들고 server.js와 엮어주기 위해 index.js에서 모듈로 불러온뒤 server로 주입(inject)한다.

//router.js
function route(pathname){
  console.log("About to route a request for " + pathname)
}

exports.route = route;
//index.js
var server = require("./server");
var router = require("./router");

server.start(router.route);
  • server모듈의 start함수의 argument로 router.route함수의 return값을 넣는다.
  • 특정 url에 접속하면(예: localhost:3000/start) About to route a request for /start가 콘솔창에 뜬다.
// server.js
var http = require("http");
var url = require("url");

//route를 파라미터로 받고있다. router.route
function start(route) {
  function onRequest(request, response){
    var pathname = url.parse(request.url).pathname;
    console.log("Request " + pathname + " received");
    response.writeHead(200, {"Content-Type": "text/plain"});

    route(pathname);

    response.write("Hello World");
    response.end();
  }

  var server = http.createServer(onRequest);
  server.listen(3000);

  console.log("Server has started.");
}

exports.start = start;

지금은 모든 pathname에서 정상 작동하지만, 몇가지 유효한 pathname에서만 행동하는 서버를 만들수 있다.

//requestHandlers.js
function start() {
  console.log("Request handler 'start' was called.");
}


function upload() {
  console.log("Request handler 'upload' was called.");
}


exports.start = start;
exports.upload = upload;
// index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;

server.start(router.route, handle);
  • handle 오브젝트에 requestHandlers모듈의 함수를 넣어준다.
  • handle을 servers.start의 argument로 추가한다.
// server.js
var http = require("http");
var url = require("url");

//route를 파라미터로 받고있다. router.route
function start(route, handle) {
  function onRequest(request, response){
    var pathname = url.parse(request.url).pathname;
    console.log("Request " + pathname + " received");
    response.writeHead(200, {"Content-Type": "text/plain"});

    //route함수의 return값을 content변수에 담는다.
    var content = route(handle, pathname);

    response.write(content);
    response.end();
  }

  var server = http.createServer(onRequest);
  server.listen(3000);

  console.log("Server has started.");
}

exports.start = start;
  • content변수를 만들어 route(router.route)의 return값을 받는다.
  • content값을 response.write에 넣어 웹페이지상에 표시하게한다.
  • pathname이 유효할경우 handle 오브젝트에 해당 함수의 return값을 반환하고, 유효하지 않을경우 404 Not found를 반환한다.
// router.js
//handle은 requestHandler모듈의 각 함수를 담은 object

function route(handle, pathname) {
  console.log("About to route a request for " + pathname);
  //pathname의 자료형이 function이 아니면 메시지를 반환한다.
  if (typeof handle[pathname] === 'function') {
    console.log("Success " + pathname);
    return handle[pathname]();
  } else {
    console.log("No request handler found for " + pathname);
    return "404 Not found";
  }
}
exports.route = route;

동기 & 비동기

results matching ""

    No results matching ""