정말로 connect 모듈에서 router 기능을 사용하신다면 아래의 번호대로 추천합니다.
1. connect 2.X 이하 버전을 추천합니다.
2. 개발자 말대로 express 모듈을 사용합니다.
3. connect-router 모듈 로 대체합니다.
4. 직접 만들어서 사용합니다.
- 해당 포스팅 내용은 직접만들어서 사용한다의 내용입니다.
아시는 바와 같이 connect 모듈은 2.x 버전부터 router 기능이 빠졌습니다.
이유는 링크에서 확인 : https://github.com/senchalabs/connect/issues/262
ㅎㅎㅎㅎㅎ 화가나더군요 ㅎㅎㅎㅎㅎ
-_- 기능상의 이유도 아니고 express를 더 열심히 만들었으니 그걸 쓰라니 그래서 있는 기능을 없애다니 ㅎㅎㅎ
(개인적으론 express를 잘쓰고 있었으나 책을 보기 전까진 connect 모듈이 있었는지도 몰랐습니다.)
짜증이 많이 났습니다. 그래서 router 부분을 구현해봤습니다.
소스다운
- 디비가 달라졌기 때문에 쿼리문은 mongoDB에 맞게 변경한 소스입니다.
mongoDB부분은 제외한 소스만 설명하겠습니다.
// 모듈을 추출합니다.
var fs = require('fs');
var connect = require('connect');
var ejs = require('ejs');
var db = require('mongojs').connect('board', ['test']);
var map = require('./Map.js');
// i = req.url , j = path
function compareUrl(i, j){
var array_str_div_i = new Array();
var array_str_div_j = new Array();
array_str_div_i = i.split('/');
array_str_div_j = j.split('/');
var array_ret = new Array();
if(array_str_div_i.length != array_str_div_j.length){
return -1;
}
for(var temp in array_str_div_i) {
if(array_str_div_j[temp].indexOf(":") == -1){
if(array_str_div_i[temp] != array_str_div_j[temp]){
return -1;
}
}else{
array_ret.push([array_str_div_j[temp],array_str_div_i[temp]]);
}
}
return array_ret;
}
function get(path, cb){
return function(req, res ,next){
if(req.method != 'GET' ){
return next();
}else if( req.url != path){
var ret = compareUrl(req.url,path);
if(ret == "-1"){
return next();
}else{
var map = new Map();
for(var temp in ret) {
if(typeof ret[temp][0] == "undefined" ){}
else{
map.put(ret[temp][0].replace(':',''), ret[temp][1]);
}
}
req.body = map;
}
}
cb(req, res, next);
}
}
function post(path, cb){
return function(req, res ,next){
if(req.method != 'POST' ){
return next();
}else if( req.url != path){
var ret = compareUrl(req.url,path);
if(ret == "-1"){
return next();
}
}
cb(req, res, next);
}
}
var app = connect();
app.use(connect.bodyParser());
// GET - /List
app.use(get('/', function (request, response) {
}));
// GET - /INSERT
app.use(get('/Insert', function (request, response) {
}));
// POST - /INSERT
app.use(post('/Insert', function (req, res) {
}));
// GET - /EDIT/:id
app.use(get('/Edit/:id', function (req, res) {
}));
// POST - /EDIT
app.use(post('/Edit/:id', function (req, res) {
}));
// GET - /DELETE/:id
app.use(get('/Delete/:id', function (req, res) {
}));
app.listen(8080, function () {
console.log('server running at http://127.0.0.1:8080');
});
1. 먼저 5번째 줄은 기존의 mysql 모듈을 빼고 mongojs를 사용하였습니다. mongojs 자세한 부분은
http://uiandwe.tistory.com/835 해당포스팅을 참조하세요.
6번째 줄의 require('./Map.js'); 부분은 get 파라미터 구현을 위하여 Map 형식의 클래스를 따로 만들었습니다.
Map 기능 출처 : http://atspeed.blogspot.kr/2011/01/javascript-hashmap.html
2. 중요한 get 함수와 post 함수입니다.
일단 connect 모듈에는 해당 함수가 없기 때문에 만들었습니다.
( 함수 원형에 대한 포스팅은 여기를 참조하세요. : http://uiandwe.tistory.com/836 )
또한 get, post 함수의 파라미터 전달방식이 다르기 때문에 함수 내용이 미묘하게 다릅니다.
먼저 get 함수 입니다.
함수원형(링크)에서 추가된부분은 if 문이 나뉘었으며 함수 compareUrl() 가 추가되었습니다.
기존 if 문은 get 이 아니거나 들어오는 링크주소가 다르면 return 으로 되어 있습니다.
만일 절대주소가 "/insert/:id" 와 접속해야되는 주소 "/insert/uiandwe" 는 같지 않기 때문에 false 가 납니다.
해서 compareUrl() 함수로 두개의 문자열을 비교합니다. (compareUrl() 함수는 3번에서 설명합니다.)
만일 비교값이 정상적이라면 해당 함수(Insert get 함수) 를 실행하며 아니라면 다음 함수로 넘어갑니다.
또한 compareUrl()에서 리턴된 배열을 통하여 파라미터를 리스트로 변환하여 req.body 에 넣습니다.
이때 리스트로 변환되는 과정에 Map.js 가 쓰입니다.
만일 "/insert/:id" , 실제 주소는 "/insert/uiandwe" 일때 리스트로 {id:uiandwe} 값이 req.body에 들어갑니다.
해당 함수에서는 req.body.get() 함수를 통하여 해당 데이터를 가져올수 있습니다.
(절대주소 "/insert/:id/:score" , 실제 주소는 "/insert/uiandwe/1" 라면 {[id:uiandwe], [score:1]} 리스트 형식으로 데이터가 넘어갑니다.)
post 함수는 get과 거의 같으나 넘겨지는 파라미터 로직은 없습니다.
파라미터는 connect 함수중 bodyParser() 로 대체 하였습니다.
bodyParser() 함수 설명 : http://www.senchalabs.org/connect/bodyParser.html
73번째 줄에서 app에 use 를 통하여 사용하는 것을 볼수 있습니다.
3. 9번째 줄의 compareUrl() 함수는 두개의 주소를 비교하는 함수입니다.
get, post 함수에 설정된 주소("/insert/:id") 와 사용자가 클릭한 주소("/insert/uiandwe") 를 비교합니다.
12번과 13번에서 두개의 주소를 /를 기준으로 잘라서 배열로 만듭니다.
15번째 if문에서 두 배열의 길이가 다르면 사용할 함수가 아니므로 return 합니다.
18번줄에서 배열만큼 탐색하며 비교합니다.
20번째줄에서 만일 비교하는 두배열의 글자가 다르다면 ("/insert/:id" 와 "/Edit/uiandwe" 의 첫번째 문자열) 잘못된 함수로 판단하고 return 합니다.
24번째 줄에서 만일 절대주소에 : 문자가 있다면 파라미터로 간주하여 해당 값을 배열에 저장하고 함수 마지막에 배열을 리턴합니다.("/insert/:id" 와 "/insert/uiandwe" 일 경우에는 ["id", "uiandwe"] 형식으로 배열에 들어갑니다.)
4. 마지막으로 해당 get 함수와 post 함수를 connect 에 적용시키기위하여 해당 함수들을 app.use()를 통하여 해당 함수들을 사용합니다.
- 장황하게 설명이 너무 길었지만 결국 직접 만들어보시는것을 추천합니다.
(완성하는데 3시간 밖에 걸리지 않았습니다. javascript 를 몰라서 많이 해멨습니다.)
- 다시 한번 말씀드리지만 DB가 책에 있던 mysql 예제에서 mongoDB로 바꾸면서 해당 쿼리 및 htm 파일의 소스도 변경되었습니다.
- 전체 소스 파일을 올렸으니 해당 파일을 확인해보시기 바랍니다.
'Node.js' 카테고리의 다른 글
node.js c9.io Error: listen EADDRINUSE 에러 발생시 (0) | 2014.02.15 |
---|---|
connect-route 모듈 이용하기 (0) | 2013.04.06 |
node.js mongojs 를 이용한 웹페이지 출력 (2) | 2013.04.04 |
connect 모듈 router 에러 발생시 (2) | 2013.04.03 |
node.js mongojs 를 이용한 mongodb 예제 (0) | 2013.04.02 |