搜了國內的文章 使用 Hapi
開發 RESTful API
的不多不多,一些 社區介紹的部分在新版本中已經不在適用,新版本中有不少變化html
RESTful API
RESTful API: REST -- REpresentational State Transfer,英語的直譯就是「表現層狀態轉移」node
能夠參考下面理解:git
理解自己的 REST 架構風格:www.infoq.com/cn/articles…github
理解 RESTful 架構:www.ruanyifeng.com/blog/2011/0…web
Restful API 設計指南:www.ruanyifeng.com/blog/2014/0…mongodb
Hapi 是一個 Node.js 的 web 框架,即一個構建應用程序和服務豐富的框架。 目前 Hapi v17 僅支持 node v8.9.0 及以上版本數據庫
server.connection 方法移除,如今使用express
const server = new Hapi.Server({ host: 'localhost', port: 3000 }) 複製代碼
開啓關閉服務方法 徹底異步,沒有回調json
try {
await server.start()
}
catch (err) {
console.log(err)
}
try {
await server.stop()
}
catch (err) {
console.log(err)
}
複製代碼
reply() 回調方法移除,response.hold() 和 response.resume() 方法不在可用api
// 之前 const handler = function (request, reply) { return reply('ok'); }; // 如今 const handler = function (request, h) { return 'ok'; }; 複製代碼
更多使用 h 的示例以下:
const handler = (request, h) => { // return a string return 'ok' // return an object and hapi creates JSON out of it return { name: 'Authentication Library', library: true } // redirect to 404 return h.redirect('/404') // return a view return h.view('index', { name: 'Authentication Library' }) // use the "h" response toolkit to create a response return h .response(thisHTML) .type('text/html') .header('X-Custom', 'my-value') .code(201) } 複製代碼
三個請求事件類型 request, request-interval, request-error 合併成一個單一的 request 事件
觸發的方法 像 server.on, request.on, response.on 被替換,使用server.events.on(), request.events.on(), response.events.on() 替代
新的請求擴展:
server.ext('onPreAuth', (request, h) => { … }) server.ext('onCredentials', (request, h) => { … }) server.ext('onPostAuth', (request, h) => { … }) ] 複製代碼
在路由定義的時候 替換 config 爲 options
server.route({ method: 'POST', path: '/', options: { … } }) 複製代碼
插件 目前使用
exports.plugin = { register, name, version, multiple, dependencies, once, pkg }
複製代碼
更多變化詳見GitHub 完整的更新日誌
在這個示例中提供 CURD 操做
A demo 有下面的屬性:
demo
├── package.json
├── server.js
├── .gitignore (可選)
└── src
├
├── controller
| └── test.js
└─── models
└── test.js
複製代碼
src/models/test.js 'use strict'; const mongoose = require('mongoose'); const Schema = mongoose.Schema; const demoModel = new Schema({ name: { type: String, required: true, index: { unique: true } }, age: { type: Number, required: true } }); module.exports = mongoose.model('Demo', demoModel, 'demos'); 複製代碼
src/controllers/test.js var Demo = require('../models/test'); /** * List Demos */ exports.list = (req, h) => { return Demo.find({}).exec().then((demo) => { return { demos: demo }; }).catch((err) => { return { err: err }; }); } /** * Get Demo by ID */ exports.get = (req, h) => { return Demo.findById(req.params.id).exec().then((demo) => { if(!demo) return { message: 'Demo not Found' }; return { demos: demo }; }).catch((err) => { return { err: err }; }); } /** * POST a Demo */ exports.create = (req, h) => { const demoData = { name: req.payload.name, age: req.payload.age }; return Demo.create(demoData).then((demo) => { return { message: "Demo created successfully", demo: demo }; }).catch((err) => { return { err: err }; }); } /** * PUT | Update Demo by ID */ exports.update = (req, h) => { return Demo.findById(req.params.id).exec().then((demo) => { if (!demo) return { err: 'Demo not found' }; demo.name = req.payload.name; demo.breed = req.payload.breed; demo.age = req.payload.age; demo.image = req.payload.image; demo.save(dogData); }).then((data) => { return { message: "Demo data updated successfully" }; }).catch((err) => { return { err: err }; }); } /** * Delete Demo by ID */ exports.remove = (req, h) => { return Demo.findById(req.params.id).exec(function (err, demo) { if (err) return { dberror: err }; if (!demo) return { message: 'Demo not found' }; demo.remove(function (err) { if (err) return { dberror: err }; return { success: true }; }); }); } 複製代碼
'use strict'; const Hapi = require('hapi'); const mongoose = require('mongoose'); const DemoController = require('./src/controllers/test'); const MongoDBUrl = 'mongodb://localhost:27017/demoapi'; const server = new Hapi.Server({ port: 3000, host: 'localhost' }); server.route({ method: 'GET', path: '/demos', handler: DemoController.list }); server.route({ method: 'GET', path: '/demos/{id}', handler: DemoController.get }); server.route({ method: 'POST', path: '/demos', handler: DemoController.create }); server.route({ method: 'PUT', path: '/demos/{id}', handler: DemoController.update }); server.route({ method: 'DELETE', path: '/demos/{id}', handler: DemoController.remove }); (async () => { try { await server.start(); // Once started, connect to Mongo through Mongoose mongoose.connect(MongoDBUrl, {}).then(() => { console.log(`Connected to Mongo server`) }, err => { console.log(err) }); console.log(`Server running at: ${server.info.uri}`); } catch (err) { console.log(err) } })(); 複製代碼
使用 postman 測試 http://localhost:3000/demos
目前步驟有點多,還須要註冊一個平臺,暫不作詳細說明了