在app.js 文件里,常用的为路由提供请求的 URL为这样
app.use('/index', require('../index.js'))
如果项目变得越来越大,并且,app端的请求端口也迭代很多版本,从v1.0升级到了v5.0。那么,很容易会导致app.js臃肿并且难为维护。
到最后,你的app.js 可能会变成这样:
app.use('/v1_0/index', require('../index1.js'))
app.use('/v1_1/index', require('../index2.js'))
app.use('/v1_2/index', require('../index3.js'))
... 此处省略47行
app.use('/v5_0/index', require('../index50.js'))
那么,怎么优化这个结构呢?
建立Node.js 的路由表,将业务逻辑都放在controller中,所有复用的版本方法都指向同一个controller中的方法。
在index.js文件里,常用的结构如此
const express = require('express');
const router = express.Router();
router.get('/', async (req, res, next) => {
res.render('index');
});
module.exports = router;
可以看到,app.use() 使用的require(‘../index1.js’),实际上是导出的router对象。
那么,我们是否可以自己定下路由表规则,去编写router对象的get/post等等过程,最后将该router导出给app.js。
创建router.js 在routers目录下
'use strict';
/**
* 定义全局路由表
* Created by davidqin on 2017/11/1.
*/
module.exports = {
/**
* admin管理
*/
'/admin': {},
/**
* 后台运营管理
* 请求路径:/operation/post_article/categories-add
* 请求方法:post
* 控制器名称:article_controller
* 对应的控制器方法:addCategories
*/
'/operation': {
'/post_article':[
'/categories-add.post.article_controller.addCategories',
'/categories-list.get.article_controller.getCategories',
'/categories-delete.delete.article_controller.deleteCategories',
'/categories-edit.put.article_controller.editCategories',
'/author-add.post.article_controller.addAuthor',
'/author-delete.delete.article_controller.deleteAuthor',
'/author-edit.put.article_controller.editAuthor',
'/author-password.put.article_controller.editAuthorPassword',
'/author-fetch.get.article_controller.fetchAuthor',
'/author-list.get.article_controller.listAuthor',
'/articles-list.get.article_controller.listArticles',
'/article-detail.get.article_controller.detailArticle',
'/article-add.post.article_controller.addArticle',
'/article-edit.put.article_controller.editArticle',
'/article-delete.delete.article_controller.deleteArticle',
],
'/article_comment':[
'/list.get.article_comment_controller.listComments',
'/add.post.article_comment_controller.addComment',
'/delete.delete.article_comment_controller.deleteComment'
]
},
/**
* APP v1.1 API
*/
'/v1_1':{
'/wikis':[
'/list.post.article_controller.listArticles',
'/detail.post.article_controller.detailArticle'
],
'/wiki-comment':[
'/add.post.article_comment_controller.addComment',
'/list.get.article_comment_controller.listComments',
'/delete.post.article_comment_controller.deleteComment'
],
'/timeday':[
'/list.get.timeday_controller.listTimeday',
'/delete.post.timeday_controller.deleteTimeday',
'/add.post.timeday_controller.addTimeday'
]
}
};
创建了路由表之后,最重要的是如何把路由表中的信息,解析出来,并且给router对象使用。最终导出router对象。
创建router_map.js 在routers目录下
'use strict';
/**
* 自动根据全局路由表,require controller控制器-方法
* Created by davidqin on 2017/11/1.
*/
const router = require('express').Router();
const routerTable = require('./router');
const _ = require('lodash');
(function loop(map) {
_.forEach(map, function (value, key) {
let controller1;
controller1 = key;
_.forEach(value, function (value2, key2) {
let controller2 = controller1;
controller2 += key2;
for (var i = 0; i < value2.length; i++) {
let controller3 = controller2;
let value3 = value2[i];
let arr = value3.split('.');
controller3 += arr[0];
let method = arr[1];
let path = '../controllers/' + arr[2] + '.js';
let fuc = arr[3];
let controllerRegistry = require(path);
let action;
for (let actionChild in controllerRegistry) {
if (actionChild === fuc) {
action = actionChild;
}
}
console.log(method, controller3, action);
router[method](controller3,controllerRegistry[action]);
}
});
});
}(routerTable));
module.exports = router;
打印出来的结果有:
post /operation/post_article/categories-add addCategories
get /operation/post_article/categories-list getCategories
delete /operation/post_article/categories-delete deleteCategories
put /operation/post_article/categories-edit editCategories
post /operation/post_article/author-add addAuthor
delete /operation/post_article/author-delete deleteAuthor
put /operation/post_article/author-edit editAuthor
put /operation/post_article/author-password editAuthorPassword
get /operation/post_article/author-fetch fetchAuthor
get /operation/post_article/author-list listAuthor
get /operation/post_article/articles-list listArticles
get /operation/post_article/article-detail detailArticle
post /operation/post_article/article-add addArticle
put /operation/post_article/article-edit editArticle
delete /operation/post_article/article-delete deleteArticle
get /operation/article_comment/list listComments
post /operation/article_comment/add addComment
delete /operation/article_comment/delete deleteComment
post /v1_1/wikis/list listArticles
post /v1_1/wikis/detail detailArticle
post /v1_1/wiki-comment/add addComment
get /v1_1/wiki-comment/list listComments
post /v1_1/wiki-comment/delete deleteComment
get /v1_1/timeday/list listTimeday
post /v1_1/timeday/delete deleteTimeday
post /v1_1/timeday/add addTimeday
第三个参数是方法名。在routers文件夹同级目录下,建立controllers文件夹,创建article_controller.js(与路由表中的控制器名称保持一致)。
创建article_controller.js,在controllers目录下。
exports.addCategories = async (req, res, next) =>{
res.send("1");
}
当有请求 post /operation/post_article/categories-add 时,会进入这个方法。你可以在多个请求URL中都指向这个方法,只要你在路由表中定义了。
const router_map = require('./server/routes/router_map');
app.use('/',router_map);
搞定。