看過node很多例子,都是將路由直接放到入口文件中處理,使得文件顯得很大很亂,特別是當一個項目變大,有上百甚至上千的路由,那該怎么辦?
最近在想如何將一個個的路由放到一個單獨的模塊中處理,比如'/users'對於users模塊。根據構想,寫了個簡單的實現,當然還有很多問題沒有考慮到,后面再補充。
目錄結構:
項目目錄
|-- routers
|-- about.js
|-- contact.js
|-- index.js
|-- router.js
|-- server.js
入口文件:server.js - 創建服務,調用router模塊的addRoute方法添加路由。
1 var http = require('http'); 2 var router = require('./router'); 3 4 router.addRoute('/', require('./routers/index')); 5 router.addRoute('/about', require('./routers/about')); 6 router.addRoute('/contact', require('./routers/contact')); 7 8 function onListened(){ 9 console.log('Node server starts at 3000.'); 10 } 11 12 function onConnected(request, response){ 13 router.handleRoute(request.url, request, response); 14 } 15 16 var server = http.createServer(onConnected); 17 server.listen(3000, onListened);
4-6行:其實還可以寫到router.js中,可以router模塊初始化是添加這些路由。這樣server.js就又變得干凈很多。
router.js - 添加路由,調用路由處理函數
1 var uuid = require('node-uuid'); 2 var http = require('http'); 3 4 function RouterData(route,handler){ 5 this.route = route||''; 6 this.handler = handler||{}; 7 this.id = uuid.v4(); 8 } 9 10 function Router(){ 11 12 var routers = []; 13 var me = this; 14 15 this.addRoute = function(route, handler){ 16 if(!route||!handler) return; 17 var routeData = new RouterData(route, handler); 18 routers.push(routeData); 19 }; 20 21 this.handleRoute = function(route, req, res){ 22 var handler = getRouteHandlerByRoute(route); 23 if(!handler){ 24 handle_404(route, req, res); 25 return; 26 } 27 handler.exec(route, req, res); 28 }; 29 30 31 function getRouteHandlerByRoute(route){ 32 var n = routers.length; 33 var handler = null; 34 for (var i = n - 1; i >= 0; i--) { 35 if(routers[i].route === route){ 36 handler = routers[i].handler; 37 break; 38 } 39 } 40 return handler; 41 } 42 43 function handle_404(route, req, res){ 44 res.writeHeader(404, { 45 'Content-Type': 'text/plain' 46 }); 47 res.end(route+' '+http.STATUS_CODES['404']); 48 } 49 50 } 51 module.exports = new Router();
為了簡單處理,addRoute方法只是簡單的添加了路由,沒有考慮到相同的情況,且在getRouteHandlerByRoute函數中的查找路由處理函數的前提是沒有相同的路由,否則得用路由uid來查找。
about.js, contact.js, index.js - 實際要處理路由的地方。
1 function About(){ 2 this.exec = function(route, req, res){ 3 res.statusCode = 200; 4 res.setHeader('Content-Type', 'text/html'); 5 res.end('This is </b>About Me</b>'); 6 } 7 } 8 9 10 module.exports = new About();
1 function Contact(){ 2 this.exec = function(route, req, res){ 3 res.statusCode = 200; 4 res.setHeader('Content-Type', 'text/html'); 5 res.end('This is </b>Contact Page</b>'); 6 } 7 } 8 9 10 module.exports = new Contact();
1 function Index(){ 2 this.exec = function(route, req, res){ 3 res.statusCode = 200; 4 res.setHeader('Content-Type', 'text/html'); 5 res.end('This is </b><strong>Home Page</strong></b>'); 6 } 7 } 8 9 10 module.exports = new Index();
在這些模塊中都實現了一個exec的方法,用於處理路由。如果更靈活處理,應該可以寫一個路由處理的基類,然后再子類繼承分別處理。
