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;