Nodejs 让express的路由支持module, controller, action格式
Nodejs 让express的路由支持module, controller, action格式
很多mvc框架都有controller和action的概念,很多后端程序员也比较熟悉,我一般是这样解决的
router.js
var siteController = require('./site.js');
var routingTable={
default:{site:siteController}
};
var dispatch = function(module,controller,action,req,res, next) {
if (module[controller]){
if (module[controller][action]){
var index = 0;
var handles = module[controller][action];
var next_handle = function(err){
if (err){
next(err);
}
else{
var handle = handles[index++];
if(!handle){
next(err);
}
else{
handle(req,res, next_handle);
}
}
};
next_handle();
}
else{
next();
}
}
else{
next();
}
};
exports.route = function(module, controller, action, req, res, next){
if(routingTable[module]){
dispatch(routingTable[module], controller, action, req, res, next);
}
else{
next();
}
};
site.js
var index_filter = function(req,res, next){};
var index = function(req, res, next){
res.render('index', {});
};
module.exports = {
index:[index_filter, index]
};
app.js
var router = require(’./roter.js’); // Routes app.get(’/’, function(req, res, next){ router.route(‘default’, ‘site’, ‘index’, req, res, next); });
app.all('/:controller', function(req, res, next){
router.route('default', req.params.controller, 'index', req, res, next);
});
app.all(’/:controller/:action’, function(req, res, next){
router.route(‘default’, req.params.controller, req.params.action, req, res, next);
});
app.get(’/:controller/:action/:id’, function(req, res, next){
router.route(‘default’, req.params.controller, req.params.action, req,res, next);
});
app.all(’/:module/:controller/:action’, function(req, res, next){
router.route(req.params.module, req.params.controller, req.params.action, req, res, next);
});
Nodejs 让express的路由支持module, controller, action格式
很多MVC框架都有Controller和Action的概念,这在后端编程中非常常见。为了在Express应用中实现类似的功能,我们可以设计一个路由分发机制,使得路由可以按照module
, controller
, action
的格式进行处理。
示例代码
首先,我们定义一个路由文件router.js
来管理路由分发逻辑:
// router.js
var siteController = require('./site.js');
var routingTable = {
default: { site: siteController }
};
var dispatch = function(module, controller, action, req, res, next) {
if (module[controller]) {
if (module[controller][action]) {
var index = 0;
var handles = module[controller][action];
var next_handle = function(err) {
if (err) {
next(err);
} else {
var handle = handles[index++];
if (!handle) {
next(err);
} else {
handle(req, res, next_handle);
}
}
};
next_handle();
} else {
next();
}
} else {
next();
}
};
exports.route = function(module, controller, action, req, res, next) {
if (routingTable[module]) {
dispatch(routingTable[module], controller, action, req, res, next);
} else {
next();
}
};
接下来,在site.js
中定义具体的Controller和Action,并且可以包含中间件:
// site.js
var index_filter = function(req, res, next) {
console.log("Index filter executed");
next();
};
var index = function(req, res, next) {
res.render('index', {});
};
module.exports = {
index: [index_filter, index] // 这里可以包含多个中间件
};
最后,在主应用文件app.js
中配置路由:
// app.js
var express = require('express');
var router = require('./router.js');
var app = express();
// 定义默认路由
app.get('/', function(req, res, next) {
router.route('default', 'site', 'index', req, res, next);
});
// 定义通用路由
app.all('/:controller', function(req, res, next) {
router.route('default', req.params.controller, 'index', req, res, next);
});
app.all('/:controller/:action', function(req, res, next) {
router.route('default', req.params.controller, req.params.action, req, res, next);
});
app.get('/:controller/:action/:id', function(req, res, next) {
router.route('default', req.params.controller, req.params.action, req, res, next);
});
app.all('/:module/:controller/:action', function(req, res, next) {
router.route(req.params.module, req.params.controller, req.params.action, req, res, next);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
- 路由分发:在
router.js
中,我们定义了一个dispatch
函数,用于根据传入的module
,controller
,action
调用相应的处理函数。 - Controller 和 Action:在
site.js
中,我们定义了具体的Controller(例如site
)以及其下的Action(例如index
),并且可以包含中间件(如index_filter
)。 - 路由配置:在
app.js
中,我们配置了各种路由模式,如根路径、通用路径等,并通过router.route
方法将请求转发给对应的Controller和Action进行处理。
这种方式可以让我们更加灵活地管理和扩展路由,同时也保持了代码的清晰性和可维护性。
赞一个
欠缺一些项目测试的经验。
根据你提供的代码示例,我们可以创建一个简单的 Express 应用程序,使其支持 module
, controller
, action
的路由结构。下面是实现这一功能的具体步骤:
- 定义路由表:我们首先需要定义路由表来映射模块到控制器。
- 创建调度函数:该函数负责处理请求并调用相应的控制器方法。
- 设置控制器:每个控制器可以包含多个方法以及中间件。
示例代码
1. 路由表 (router.js
)
const express = require('express');
const app = express();
const siteController = require('./controllers/site');
const routingTable = {
default: {
site: siteController
}
};
const dispatch = (module, controller, action, req, res, next) => {
if (module[controller]) {
if (module[controller][action]) {
const handlers = module[controller][action];
let i = 0;
const nextHandler = () => {
if (i >= handlers.length) return next();
const handler = handlers[i++];
handler(req, res, nextHandler);
};
nextHandler();
} else {
next();
}
} else {
next();
}
};
const route = (module, controller, action, req, res, next) => {
if (routingTable[module]) {
dispatch(routingTable[module], controller, action, req, res, next);
} else {
next();
}
};
app.use((req, res, next) => {
route(req.params.module, req.params.controller, req.params.action, req, res, next);
});
module.exports = route;
2. 控制器 (controllers/site.js
)
const indexFilter = (req, res, next) => {
console.log("Index Filter Executed");
next();
};
const indexAction = (req, res) => {
res.send("Site Index Page");
};
module.exports = {
index: [indexFilter, indexAction]
};
3. 主应用文件 (app.js
)
const express = require('express');
const app = express();
const route = require('./router');
app.set('views', './views');
app.set('view engine', 'ejs');
app.get('/', (req, res, next) => {
route('default', 'site', 'index', req, res, next);
});
app.all('/:controller', (req, res, next) => {
route('default', req.params.controller, 'index', req, res, next);
});
app.all('/:controller/:action', (req, res, next) => {
route('default', req.params.controller, req.params.action, req, res, next);
});
app.get('/:controller/:action/:id', (req, res, next) => {
route('default', req.params.controller, req.params.action, req, res, next);
});
app.all('/:module/:controller/:action', (req, res, next) => {
route(req.params.module, req.params.controller, req.params.action, req, res, next);
});
app.listen(3000, () => {
console.log('App is running on http://localhost:3000');
});
解释
- 路由表 (
routingTable
) 定义了模块到控制器的映射关系。 - 调度函数 (
dispatch
) 负责调用控制器中的方法,并允许使用中间件。 - 主应用文件 (
app.js
) 设置了不同类型的路由,并将请求传递给路由处理函数 (route
)。
这种方式可以使你的 Express 应用更接近传统的 MVC 模式,使得路由更加清晰和易于维护。