您的位置:首页 > Web前端 > Node.js

第8章-使用Express.js和Hapi构建Node.js-REST-API服务-8.4.重构:使用Hapi搭建REST API服务器

2017-06-18 19:02 1226 查看
Hapi是一个企业级的框架。他比Express.js复杂,功能更加丰富,更适合大团队开发使用。由Walmart Labs的Eran Hammer维护。

Hapi是一个框架,他的日志功能十分强大。

安装好Hapi后

一、创建程序入口文件hapi-app.js

//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()


二、Hapi相对于Express.js的不同之处

1.使用数组定义路由规则

2.使用method、path、handler等属性定义路由对象

3.使用loadCollection方法替代中间件

4.在URL中使用{name}格式替换:name格式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息