Node.js
정말 마음에 드는 엔진이다. 재밌는 자바스크립트로 서버까지~
이제부터 공부해봐야겠다.
1. Hello World 출력
뭘 하던 이것부터 ~_~
1) util API 불러와서 출력하기
setTimeout(function(){
sys.puts("world");
}, 2000);
sys.puts("hello");
2) STDOUT 출력하기
2. HTTP 서버 모듈 생성
1) 코드
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;