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

xiaoxiao2021-02-28  132

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格式

转载请注明原文地址: https://www.6miu.com/read-29990.html

最新回复(0)