Hapi是一个企业级的框架。他比Express.js复杂,功能更加丰富,更适合大团队开发使用。由Walmart Labs的Eran Hammer维护。
Hapi是一个框架,他的日志功能十分强大。 安装好Hapi后
//1.引入依赖模块
var hapi = require('hapi'), mongoskin = require('mongoskin'),//2.创建一个Hapi服务器对象
server = hapi.createServer('localhost', 3000)//3.连接数据库
var db = mongoskin.db('mongodb://@localhost:27017/test', {safe:true}) var id = mongoskin.helper.toObjectID//4.定义方法,接收数据库名参数,然后异步加载数据库。接收的参数是URL,返回值是数据库集合
var loadCollection = function(name, callback) { callback(db.collection(name)) }//5.这里和Express.js差异最大。 //我们需要把路径、回调函数等信息作为属性传入,而且在回调中第二个参数是reply而不是Express.js中的res(或response) //server.route()函数接收一个数组做参数,每条路由是数组的一个元素 //这里第一条路由给主页使用(“/”)
server.route([ { method: 'GET', path: '/', handler: function(req, reply) { reply('Select a collection, e.g., /collections/messages') } },//6.用来响应GET /collection/:collectionName请求,其中主要的处理逻辑是在回调函数中调用loadCollection方法。 //这个方法用来查询相关的对象(find({})),然后输出排序并消减条目(最后10条)之后的结果:
{ method: 'GET', path: '/collections/{collectionName}', handler: function(req, reply) { loadCollection(req.params.collectionName, function(collection) { collection.find({}, {limit: 10, sort: [['_id', -1]]}).toArray(function(e, results){ if (e) return reply(e) reply(results) }) }) } },//7.用来创建一个新对象(POST /collections/collectionName),使用loadCollection方法,然后调用insert方法,并把请求数据(req.paylod)传入
{ method: 'POST', path: '/collections/{collectionName}', handler: function(req, reply) { loadCollection(req.params.collectionName, function(collection) { collection.insert(req.payload, {}, function(e, results){ if (e) return reply(e) reply(results) }) }) } },//注:URL中的每个参数都需要放在{}之中,同Express.js中使用的:name形式有所区别。因为”:”本身是一个合法的RUL字符,所以如果把他用作变量界定符的话,那么就没办法在URL中正常使用他了。 //8.通过对象ID获取单条记录
(/collection/collectionName/id) { method: 'GET', path: '/collections/{collectionName}/{id}', handler: function(req, reply) { loadCollection(req.params.collectionName, function(collection) { collection.findOne({_id: id(req.params.id)}, function(e, result){ if (e) return reply(e) reply(result) }) }) } },//9.更新记录,根据URL中的collectionName参数,调用loadCollection方法,来获取相应的数据库集合
{ method: 'PUT', path: '/collections/{collectionName}/{id}', handler: function(req, reply) { loadCollection(req.params.collectionName, function(collection) { collection.update({_id: id(req.params.id)}, {$set: req.payload}, {safe: true, multi: false}, function(e, result){ if (e) return reply(e) reply((result === 1) ? {msg:'success'} : {msg:'error'}) }) }) } },//10.删除记录,先通过URL中的参数(collectionName)获取到响应的元素集合,然后通过ID删除这些元素,并返回结果(成功或者失败)
{ method: 'DELETE', path: '/collections/{collectionName}/{id}', handler: function(req, reply) { loadCollection(req.params.collectionName, function(collection) { collection.remove({_id: id(req.params.id)}, function(e, result){ if (e) return reply(e) reply((result === 1) ? {msg:'success'} : {msg:'error'}) }) }) } } ])//11.控制日志的配置
var options = { subscribers: { 'console': ['ops', 'request', 'log', 'error'] } }; server.pack.require('good', options, function (err) { if (!err) { // 插件加载成功 } });//12.启动服务
server.start()1.使用数组定义路由规则 2.使用method、path、handler等属性定义路由对象 3.使用loadCollection方法替代中间件 4.在URL中使用{name}格式替换:name格式