본문 바로가기

Node.js

connect 모듈 router 기능 구현

정말로  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 부분을 구현해봤습니다.


소스다운 

node.js-mongodb-ex.zip


- 디비가 달라졌기 때문에 쿼리문은 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 파일의 소스도 변경되었습니다. 

- 전체 소스 파일을 올렸으니 해당 파일을 확인해보시기 바랍니다.