Server/node.js

Node.js

kirhieyes 2011. 12. 24. 02:34

정말 마음에 드는 엔진이다. 재밌는 자바스크립트로 서버까지~

이제부터 공부해봐야겠다.

1. Hello World 출력
    뭘 하던 이것부터 ~_~

1) util API 불러와서 출력하기
var sys = require("util")
setTimeout(function(){
 sys.puts("world");
}, 2000);
sys.puts("hello");

2) STDOUT 출력하기
console.log("Hellow World");

 2. HTTP 서버 모듈 생성

1) 코드

var http = require("http");

http.createServer(function(req, res){
 res.writeHead(200, {"Content-Type": "text/plain"});
 res.write("Hello World");
 res.end();
}).listen(8080);

http://localhost:8080/ 에 접속하면 "Hello World" 가 찍히는 웹페이지를 볼 수 있다.
서버 모듈을 생성하면서 이벤트가 발생하면 호출할 callback 함수로 익명함수를 인자로 넘겼다. 이제 이벤트가 없을 경우에는 아무런 동작도 안하지만 이벤트가 발생하면 인자로 넘긴 익명함수가 호출될 것이다.

var http = require("http");

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

http.createServer(onRequest).listen(8080);

console.log("Server has started");


즉 node.js의 핵심 정의는 callback을 가진 이벤트 드리븐 비동기 서버사이드 JavaScript 이다!!

2) 코드 리뷰
callback으로 익명함수(위에서는 onRequest)가 호출될때 request 와 reponse 객체가 넘어온다.
요청이 들어올 때마다 res.writeHead() 함수를 사용해 HTTP status 200과 content-type을 응답헤더로 보내고, res.write() 함수로 "Hello World"를 응답 body로 보낸다.
그리고 res.end() 로 응답을 마무리한다.

3. 모듈화
   server.js를 Node.js 모듈로 만들어서 다른 파일에서 사용할 수 있게 한다.
   현재 server.js 의 기능은 http 서버를 시작하는 것이다. 따라서 시작하는 메서드를 만들고 이를 export 해주면 된다.

var http = require("http");

function start(){
 function onRequest(req, res){
  console.log("Request received");
  res.writeHead(200, {"Content-Type":"text/plain"});
  res.write("Hello World");
  res.end();  
 }
 
 http.createServer(onRequest).listen(8080);
 console.log("Server has started"); 
}

exports.start = start;


이제 index.js 파일을 만들고 HTTP 서버를 시작시킨다.

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

server.start();



파일을 require 하고 지역변수에 할당하면 export 된 함수를 쓸 수 있게 된다.
이렇게 서로 다른 파일들을 모듈로 만들어 서로 엮을 수 있다.
이제 서로 다른 요청에 대해 응답하기 위해 route를 만들어 보자.

4. route
다른 HTTP 요청을 구분하여 각각에 맞는 응답처리파일을 가리키도록 하는 것을 "라우팅(routing)"이라고 한다.
요청 URL 과 GET/POST 파라미터를 router 로 전달하면 router 는 어떤 코드를 실행할 지 결정해야 한다.
따라서 HTTP 요청에서 URL 과 GET/POST 파라미터를 뽑아내야 한다. 이것을 route 부분에서 구현하는지 server 부분에서 구현하는지에 대한 논란은 있다.
일단은 HTTP server 의 일부로 만들어보자.

현재 우리에게 필요한 모든 정보를 request 객체를 통해 접근할 수 있다. 하지만 이 정보를 얻어 내기 위해 url 과 querystring 이라는 모듈이 추가로 필요하다.
- url 모듈 : URL 의 각각의 부분 (ex. URL path, query string)을 뽑아낼 수 있는 메서드를 제공한다.
- querystring 모듈 : query string 을 request 파라미터로 파싱하는 메서드를 제공한다. 또한 POST 요청의 body를 파싱한다.

1) URL path 가 무엇인지 파악하는 로직 작성(server.js)

var http = require("http");
var url = require("url");

function start(){
 function onRequest(req, res){
  var pathname = url.parse(req.url).pathname;
  console.log("Request for " + pathname + " received");
  res.writeHead(200, {"Content-Type":"text/plain"});
  res.write("Hello World");
  res.end();  
 }
 
 http.createServer(onRequest).listen(8080);
 console.log("Server has started"); 
}

exports.start = start;


이제 URL path 를 기반으로 요청을 request handler 로 매핑하는 router를 만들 수 있다.

2) 요청에 따라 교통정리를 하는 router.js

function route(pathname){

   console.log("About to route a request for " + pathname);

}

exports.route = route;

- server.js 의 확장부분

var http = require("http");
var url = require("url");

function start(route){
 function onRequest(req, res){
  var pathname = url.parse(req.url).pathname;
  console.log("Request for " + pathname + " received");

  route(pathname);
  res.writeHead(200, {"Content-Type":"text/plain"});
  res.write("Hello World");
  res.end();  
 }
 
 http.createServer(onRequest).listen(8080);
 console.log("Server has started"); 
}

exports.start = start;

- index.js 에서 server 에 route 주입

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

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

server.start(router.route);

3) 다중 요청 처리를 위해 requestHandlers 만들기

function start(){

   console.log("Request handler 'start' was called.");

}

function upload(){

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

}

exports.start = start;

exports.upload = upload;

- requestHandler의 리스트를 객체로 넘기고 index에서 받아서 route로 주사한다.

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

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

var requestHandler = require("./requestHandlers");

var handle = {};

handle["/"] = requestHandlers.start;

handle["/start"] = requestHandlers.start;

handle["/upload"] = requestHandlers.upload;

server.start(router.route);


- server.js 도 여기에 맞춰 수정

var http = require("http");
var url = require("url");

function start(route){
 function onRequest(req, res){
  var pathname = url.parse(req.url).pathname;
  console.log("Request for " + pathname + " received");

  route(handle, pathname);
  res.writeHead(200, {"Content-Type":"text/plain"});
  res.write("Hello World");
  res.end();  
 }
 
 http.createServer(onRequest).listen(8080);
 console.log("Server has started"); 
}

exports.start = start;


- route.js 에 handle 받을 수 있게 수정

function route(handle, pathname){

   console.log("About to route a request for " + pathname);

   if(typeof handle[pathname] === 'function'){

     handle[pathname]();

   }else{

     console.log("No request handler found for " + pathname);

   }

}

exports.route = route;