Enrouten:用于 Express 的路由(route)配置中间件(初始化与配置模块)https://github.com/paypal/express-enrouten

我觉得这称不上一个中间件,为什么!express或者说connect的中间件,至少要有截获和转发request的功能吧,所以这个最多成的上是对express原有route功能的增强。其实看了他的代码,我觉得非常熟悉,因为我的route代码也是这么设计的,哈哈。

我使用Nodejs的时候,有一点不爽就是,对于route的注册和实现是分离的,route的注册是在app.js里面,而route的实现是放在route.js里面的,很多时候,如果要添加一个route,就不得不同时修改2个文件,这不仅给开发,还给维护带来很大的不变,我觉得Enrouten这个小框架可能就是为了解决这个问题。先看看他的代码实例:

一、注册route,Enrouten支持2种注册route的方法,一个是指定一个目录,一个是指定一个route的定义集合。

// 第一种方法
enrouten(app).withRoutes({directory: 'controllers'
});// 第二种方法
enrouten(app).withRoutes({routes: [{ path: '/',    method: 'GET', handler: require('./controllers/index') },{ path: '/foo', method: 'GET', handler: require('./controllers/foo') }]
});

对于第一种方法,Enrouten会遍历改目录下所有的js文件,假如那个js文件export出来的是一个函数且仅仅是一个函数,那么就调用那个函数,并且传入express的实例,那个,这个函数该怎么写呢:

module.exports = function (app) {app.get('/', function (req, res) {// ...});
};

明白了吧,这个函数就把原来在app.js代码,移到了route内部(在Enrouten里面应该叫做controller吧)

对于第二种方法,我再贴一遍代码:

// 第二种方法
enrouten(app).withRoutes({routes: [{ path: '/',    method: 'GET', handler: require('./controllers/index') },{ path: '/foo', method: 'GET', handler: require('./controllers/foo') }]
});

这个代码很有误导性,看上去,好像已/foo开头的route都定义在了./controllers/foo那个文件里面,通过这个定义,就可以把所有对foo的request都handle了。但可是,可但是实际上是什么呢?Enrouten只不过,遍历这个数组,对里面每个route定义,调用app[method](def.path, def.handler),说的再明白点,就是app.get("/foo", handler)。所以没什么大花头哦。

好,再来看看我自己的设计,我有个名为AbstractRoute的基类,里面有一个公共的函数addRequestHandlers,这个函数需要你传入express实例,然后会调用受保护的_addRequestHandlers工具函数,这个工具函数和Enrouten做的差不多,挨个遍历定义,然后帮你注册routes。

"use restrict";
_ = require('underscore')
should = require('should')module.exports = class AbstractRoute
#public:addRequestHandlers: (server)->@_addRequestHandlers(server, [])#protected:_addRequestHandlers: (app, routeRequests)->should.exist(app, routeRequests)for routeRequest in routeRequestsmethod = app[routeRequest.method] || app.getmethod.call(app, routeRequest.url, _.bind(routeRequest.handler, @))

这个是每个route的代码,从AbstractRoute继承,重写addRequestHandlers函数,把route定义传给_addRequestHandlers()函数。

module.exports = class CerRoute extends AbstractRoute
#public: addRequestHandlers: (@m_app) ->should.exist(@m_app)routeRequests = [new RouteRequest("get", "/", @handleIndexPage)new RouteRequest("get", "/cer/:idType(group|product)/:id", @handleProductIndexPage)new RouteRequest("get", "/cer/:idType(group|product)/:id/index", @handleAjaxProductIndex)new RouteRequest("get", "/cer/:idType(group|product)/:id/topCrashCommands", @handleAjaxTopCrashCommands)new RouteRequest("get", "/cer/:idType(group|product)/:id/weeklyCrashCount", @handleAjaxWeeklyCrashCount)new RouteRequest("get", "/cer/:idType(group|product)/:id/weeklyCrashCountPerUser", @handleAjaxWeeklyCrashCountPerUser)new RouteRequest("get", "/cer/:idType(group|product)/:id/fixRate", @handleAjaxFixRate)new RouteRequest("get", "/cer/:idType(group|product)/:id/osBreakDown", @handleAjaxOsBreakDown)new RouteRequest("get", "/cer/:idType(group|product)/:id/bucket", @handleAjaxBucket)new RouteRequest("get", "/cer/:idType(group|product)/:id/realTimebucket", @handleAjaxRealTimebucket)#new RouteRequest("get", "/cer/:idType(group|product)/:id/dataMining", @handleAjaxDataMining)new RouteRequest("get", "/cer/:idType(group|product)/:id/sendReport", @handleAjaxSendReport)new RouteRequest("post", "/cer/:idType(group|product)/:id/postReport", @handleAjaxPostReport)new RouteRequest("get", "/cer/:idType(group|product)/:id/data/researchRate", @handleDataGetResearchRate)new RouteRequest("get", "/cer/:idType(group|product)/:id/data/fixRate", @handleDataGetFixRate)]@_addRequestHandlers(@m_app, routeRequests)

RouteRequest又是一个类,很简单很简单:

should = require('should')module.exports = class RouteRequestconstructor: (@method, @url, @handler)->should.exist(@method, "parameter 'method' can not be null")should.exist(@url, "parameter 'url' can not be null")should.exist(@handler, "parameter 'handler' can not be null")

在app.js里面的调用也很简单:

cerRoute = new (require('./lib/route/CerRoute'))();
cerRoute.addRequestHandlers(server);

我这样设计有2个优点:

1. 面对对象

2. 把route的注册和实现放在一个类/文件里面,好管理,好维护。

缺点:

1. 没有考虑到,把这个AbstractRoute作为一个单独的module独立出来,变成一个框架 :)

转载于:https://www.cnblogs.com/puncha/p/3876863.html

Paypal开源nodejs框架研究(二)KrakenJs之Enrouten相关推荐

  1. paypal之nodejs 框架 Kraken-js 源码分析

    本文是基于 kraken-js 0.6.1 版本的 关于如何使用kraken-js 可以去看看官网的使用文档 点击这里 .kraken-js 是基于express之上的,目的在于让工程师更多的去关注代 ...

  2. Quartz.NET开源作业调度框架系列(二):CronTrigger-转

    CronTriggers比SimpleTrigger更加的灵活和有用,对于比较复杂的任务触发规则,例如"每个星期天的晚上12:00"进行备份任务,SimpleTrigger就不能胜 ...

  3. .NET 5 开源工作流框架elsa技术研究

    编者注: 工作流框架 elsa 是.NET基金会下面的开源项目,2.0版本即将在3月份发布,目前正在紧锣密鼓的开发之中,2020年2月份我也介绍过推荐一个很棒的开源工作流elsa-core ,今天给大 ...

  4. Java开源 J2EE框架(二)

    Java开源 J2EE框架(二) 2007-01-06 12:34 Jofti [Java开源 其它开源项目] Jofti可对在缓存层中(支持EHCache,JBossCache和OSCache)的对 ...

  5. Html node.js开源项目,2020年面向开发人员的十大NodeJS框架

    Node.js 是一个基于 Chrome V8 引擎的,开源的,跨平台的 JavaScript 运行环境.事件驱动的.非阻塞 I/O 模型使 NodeJS 框架 能够开发极其轻便且高效的 Web 应用 ...

  6. python 量化交易 框架 开源_Hikyuu首页、文档和下载 - 基于 C++/Python 的开源量化交易研究框架 - OSCHINA - 中文开源技术交流社区...

    Hikyuu Quant Framework是一款基于C++/Python的开源量化交易研究框架,用于策略分析及回测.其核心思想基于当前成熟的系统化交易方法,将整个系统化交易抽象为由市场环境判断策略. ...

  7. python量化交易开源框架_hikyuu: 基于C++/Python的开源量化交易研究框架

    Hikyuu Quant Framework是一款基于C++/Python的开源量化交易研究框架,用于策略分析及回测(仅受限于数据,如有数据也可用于期货等).其核心思想基于当前成熟的系统化交易方法,将 ...

  8. php 量化交易 开源,hikyuu开源量化交易研究框架 v1.0

    Hikyuu Quant Framework是一款基于C++/Python的开源量化交易研究框架,用于策略分析及回测(仅受限于数据,如有数据也可用于期货等).其核心思想基于当前成熟的系统化交易方法,将 ...

  9. python 股票自动交易助手_hikyuu: 基于C++/Python的开源量化交易研究框架

    Hikyuu Quant Framework是一款基于C++/Python的开源量化交易研究框架,用于策略分析及回测(仅受限于数据,如有数据也可用于期货等).其核心思想基于当前成熟的系统化交易方法,将 ...

  10. 数字货币综合虚拟货币交易平台源码(基于thinkphp框架)中英文切换适合学习研究 二开

    源码简介: 数字货币合约交易源码,综合虚拟货币交易平台源码(基于thinkphp框架)中英文切换 支pc+h5 持委托交易,买卖交易市场等等功能 这个框架适合二开 好多比较好一点的交易所都是基于这个二 ...

最新文章

  1. 打发无聊的办法(2005-5-31)
  2. 洛谷P1032 字串变换
  3. mysql主从复制,半同步,主主复制架构的实现
  4. WebBrowser的Cookie操作(与CookieContainer的关系)
  5. css中伪类与伪元素的区别
  6. datetime2 数据类型
  7. matlab的数学函数,matlab中常见数学函数的使用
  8. Android客户端与服务器之间传递json数据
  9. 漫画 | 面试的我 VS 真实的我
  10. pyqt5中的lineEdit中只输入数字和字母
  11. 软件定义无线电matlab书,软件定义无线电
  12. 编译原理0909的作业
  13. java线程池饱和策略_干货:Java几种线程池的分析和使用。
  14. 谈谈作为DBA我对MySQL数据库优化的理解
  15. U盘有必要安全弹出吗??
  16. 编译原理-回溯法及其优化的思考
  17. NET 2.0(C#)调用ffmpeg处理视频的方法
  18. MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
  19. [javascript]替换所有带/的字符串
  20. ORA-01950: no privileges on tablespace ‘USERS‘

热门文章

  1. 达观杯文本分类——基于N-gram和LogisticRegression
  2. Redis安装(源码安装)
  3. [禅悟人生]将所学转化成修行
  4. Android系统的Binder机制之二——服务代理对象(1)
  5. hdu 1536 S-Nim (sg)
  6. J2ME 模拟短信发送界面开发程序
  7. Linux 重启命令
  8. 文件解压缩,删除文件,创建文件,读取xml文件为json字符串,得到相对路径下的图片名称...
  9. 关于如果减少勒索病毒的侵扰:
  10. hadoop集群常见问题解决