第一次尝试发布npm,简化Express路由配置并添加拦截器功能的Rainbow
发布于 11 年前 作者 mytharcher 10381 次浏览 最后一次编辑是 8 年前

安装:

$ npm install rainbow

项目主页:https://github.com/mytharcher/rainbow

中文介绍:发布npm包Rainbow

欢迎各位围观指正!


Update

0.0.2 (2012-12-11)

  • 修复自定义相对路径容错问题。

0.1.0 (2012-12-24)

  • 新增params方式配置参数化URL支持。
  • 修复不区分get/post/put/delete路由时的filter支持问题。
19 回复

首先非常感谢高手提供的轮子,但是看完介绍后还是不太会用~~比如我有3个action:/update,/delete,/add,就是微博的修改、删除和增加,我希望对这3个action设置登录拦截而比如/reg,/login这两个action不设置拦截应该怎么做,还有就是如果我给这三个不但要设置登录拦截还想在设置一个字符拦截给/update,/add,这两个action的话可以吗

可能我文档里的例子没说明白。

根据你的情况,首先把update.js等3个action放到controllers/目录,另外,我觉得你说的登录拦截,应该是一个跳转吧,那么reg.jslogin.js也应该是真实的action,也应该放到controllers/下。

这时设计你的登录拦截器,比如叫authorization.js,放到filters/目录下,内容:

module.exports = function (req, res, next) {
    if (!req.session.user) {
        res.redirect('/login'); // session中没有user认为是没有登录,跳到注册页
    } else {
        next(); // 通过的话继续后续操作
    }
};

controllers/update.js里这么写:

exports.post = function (req, res, next) {
    // 通过拦截器后你自己的业务逻辑
    res.send(200, 'OK');
};
// 添加拦截器,指明通过登录验证才可以继续
exports.post.filters = ['authorization'];

还要加其他拦截器的话都可以在filters数组里加,会顺序执行。

不知道说明白没,你可以再试试。

差不多清楚了 这样的话其实也是针对每一个action的跳转逻辑方法,后面都跟着一句拦截他的拦截器集合(exports.post.filters = ['authorization'])代码是吧,也就是比如我那3个action每个后面都要紧跟着写,如

exports.update= function (req, res, next){...}
exports.update.filters = ['authorization'];

exports.delete= function (req, res, next){...}
exports.delete.filters = ['authorization'];

exports.add= function (req, res, next){...}
exports.add.filters = ['authorization'];

是这样吗

@duyinghua 方法名不能叫updateadd,我文档里写了,对应URL的文件里,如果要使用RESTful的方法,exports的方法就只能叫get/post/putdelete

而你的需求应该是把文件名改成update.js,对应里面写post方法。否则你就需要统一你对该资源的URL,然后在同一个文件中定义对应RESTful的CURD方法。

@mytharcher 哦哦 多谢,明白了,不过这样的话就只能给每个action单独放在一个js里 而且每个这样的js都要写个类似exports.add.filters = ['authorization'];的拦截器集合了吧,看起来是简洁清晰了许多,但是过滤器这种东西分散放置的话是不是不便于维护呢,仅仅是个人建议,呵呵

@duyinghua 一般来说过滤器都是权限验证或者参数检查之类的,业务不是很复杂的话多不到那里去。而且也都是有明确含义的,所以离散的放置在一个目录里比较合适。当然,这里有个小trick,引入的过滤器由于使用的是require,所以名称里是可以带路径的。也就是说你可以在filters/目录下再创建更多的目录来分类放置你的过滤器(如果你一定要的话)。

PS再强调一下:exports.add这种写法在Rainbow里是无效的,如果要使用RESTful的方式定义,那么你这个添加的方法名只能叫exports.put。同时在前端请求这个资源的时候也只能使用put方法。

现在考虑支持/:id类型的URL映射,想征集下大家需求。如果是只有一个参数的话应该很容易改进,但同一个URL上有多个类型的话API设计就比较麻烦。

我想知道单一参数是否可以满足90%的情况?

我提个建议吧,既然你已经封装了express的路由那么可以利用express的路由方法,express里面已经定义了 params 的参数规则。可以依靠自己编写正则表达式来限制路由参数的类型。假如想要加进去把他封装成api应该就可以了。 仅仅是个建议。我也只是看过那部分express的源码。

@firstgeniusboy 嗯,我也准备利用这个,这样在具体使用的时候和原生的完全没有差异。

现在考虑的是准备添加一个参数给每个action,比如在一个controller里:

exports.get = function (req, res, next) {
    req.params.xxx; // in use
};
exports.get.params = '/:xxx';

这样形式的,当检测到某个action带有params(或者其他名字)的配置,就拼接上这部分到URL的路由里。

已经完成支持字符串和正则方式配置的params解析,详细使用见Rainbow中文文档

赞 补上测试,模块就完整了.

东东不错,但是发布到npm中要让人放心使用,单元测试和持续集成是需要的。可以参见https://github.com/JacksonTian/unittesting 补上测试。

感谢指导!不过毕竟开源的东西没有太多精力来维护,我有时间的时候再去研究下测试框架。

@mytharcher 没有精力维护也就意味着用户的流失

@mytharcher 我有空一定看看你的东东,我也打算写一个 controller 版本,基本构思不需要配置直接跳转 controller.action。并且兼容 express的 params。

@firstgeniusboy 已经兼容了,源码就40多行

@mytharcher 我的意思是你的东东是否可以兼容 ,express 对 params 的预处理。

@firstgeniusboy 我只做了params的拼接,所以理论上是跟原生的效果一样的。

回到顶部