《 Node.js项目实践:构建可扩展的Web应用》试读
我对Node.js的看法
node.js是基于chrome的js运行引擎(俗称v系列, 特点就是快)运行的服务器脚本语言,用于方便地搭建响应速度快、扩展方便的网络服务。之所以快速高效得益于它的非阻塞IO和便捷的事件驱动。
为什么我们要使用Node.js?
处理高并发能力强,而且基于函数式编程使得异步回调变的非常简单。
还有一点就是前后分离时在后端的web层到底是应该谁来开发的问题,因为web层除了拼页面外还有一些关联前端比较多的工作,这部分工作交由后端做呢,不能很好的理解其中的一些功能需求及一些技术,拿拼页面讲,后端人员真的只是拿做好的html进行拼接;交由前端做呢,很多前端人员并不熟悉类似java、php等语言所以效果不佳,但是,node.js的出现解决了这个问题,前端人员运用熟悉的js也能完成web的一些工作,而后端人员只要考虑编写借口api就OK了。
本书节选试读
试读的节选是第3章:node.js基于mocha的测试,第6章:node.js使用session和oauth进行验证,第8章:使用express和hapi构建rest服务。
从本书的目录来看本书从node的安装,helloworld的编写,到实践开发,工具的运用等一条龙非常详细。
TDD测试驱动开发是一种重要的敏捷开发技术,有效地提升代码质量、改进错误改进方式,使得开发更有效率。
oauth验证也是目前业内非常流行的标准验证授权。
Rest服务是富客户端和API服务端的标志,rest化的服务端能服务多种形式的客户端,包括手机移动端、其他服务端及富客户端的PC。
安装mocha
使用npm安装mocha
mocha提供以下有用的服务:
- 支持测试报告
- 异步运行模式
- 丰富的配置选项
命令使用:
mocha test.js [options] 具体的options不作介绍。
hock机制,即before(), beforeEach(), after(), afterEach()提供各个执行阶段的hock。
用assert进行测试
assert是核心功能,通过require('assert')来获取该模块。
var assert = require('assert'); assert.equal(1,1,'1===1');
类似上面的代码进行测试。
用expect.js进行行为驱动开发
expect.js是BDD测试,链式语法,使用更加贴近自然语言。
写个断言有几种方式,expect(response).to.be(true)和expect(response).equal(true)
- ok/true: 检查是否为真
- to.be, to: 连接方法
- not: expect(response).not.to.be()
- a/an: 检测类型
- contain/include: 数组包含
- above/below: 检测大于小于
测试实例
略
express.js中间件权限管理
配置路由进行验证
app.get('api/get', auth);//只对GET api/get进行拦截 app.all('api/*', auth);//对所有方式,且以api开头的请求进行拦截
var auth = function(req, res, next) { //验证 //如果不通过 next(new Error('Not authorized')); //or res.send(401); return next(); }
基于token的权限验证
所谓token验证即在请求的数据或者header中携带token参数,然后在auth中验证token是否合法,一般还用一些加密。
基于session的权限验证
目前普遍的做法,但是由于一些原因客户端并不能很好地支持cookie,所以有上面的token验证。
session验证就是获取cookie中的sessionid或者其他方法获取sessionid,然后通过sessionid获取session判断是否有权限。
本章介绍了如何使用cookie和session。
项目实践
everyauth实现auth1.0/2.0 略
Restful认识
restful就是客户端的请求是无状态的,服务器不保存客户端请求状态,所以保证可以被任意服务器处理,具有以下特征。
- 扩展性强,可以将部件独立部署。
- 使用简单的动作和内容替代soap。
- 使用不同的http方式表示不同的动作,GET、POST、DELETE、PUT、OPTIONS
- 内容不局限于json,还可以是xml,csv
GET、DELETE、PUT都是幂等性。
项目依赖
依赖express、mongoskin
使用Mocha和superagent进行测试
SuperAgent链式函数使得http请求非常方便,使用TDD方式开发。
it('post object', function(done){ superagent .post('http://localhost:3000/collections/test') .send({ name: 'John', email: '[email protected]' }) .end(function(e,res){ expect(e).to.eql(null); expect(res.body.length).to.eql(1); expect(res.body[0]._id.length).to.eql(24); id = res.body[0]._id done(); }); });
上面的测试代码表示:
- 返回的错误对象为空null
- 返回的数据对象数组长度为1
- 返回的数据组第一个对象的_id长度为24
express构建rest
我们使用bodyParser.urlencoded()和bodyParser.json()来获取参数和数据,这样可以获取rest的url中的参数,和传输过来的数据。
app.param('collectionName', function(req, res, next, collectionName){ req.collection = db.collection(collectionName); return next(); })
上面的代码表示所有路由中包含collectionName时会拦截进行执行,将mongo的collection绑定在req请求对象上。
app.get('/collections/:collectionName', function(req, res, next) { req.collection.find({},{ limit:10, sort: [['_id',-1]] }) .toArray(function(e, results){ if (e) return next(e); res.send(results) }); });
拦截GET方法,查询对应的collection的,并且限制10个。
hapi构建rest
hapi比express更加复杂,更加丰富。
基本上和express差不多,区别的地方如下:
- path参数使用{}而不是:
- 路由定义是数组,这样可以一次定义多个路由
- 定义路由时使用path,method,handler回调函数
- 使用reply而不是response,返回数据
总结
本书还是非常实在地从项目开发的各个角度出发对node的使用作全方位的讲解,还有一个特点是本书的代码实例量恰到好处,非常详细又不会啰嗦地使用代码来说明使用方式这样对初学者或者首次使用这些工具的开发者都能很便捷地起步。
不过偏实战的书对具体深入还是不够,抑或试读部分是这样的其实整书又是另一番风景,这里这是窥豹一斑啊!所以,还是求书仔细阅读。