Using Hapi to develop RESTful APIS is very rare. Some community introduction parts are no longer applicable in the new version. There are many changes in the new version
What is theRESTful API
REpresentational State Transfer REpresentational State Transfer
Can refer to the following understanding:
-
Understand itself REST architectural style: www.infoq.com/cn/articles…
-
Understanding a RESTful architecture: www.ruanyifeng.com/blog/2011/0…
-
Restful API design guidelines: www.ruanyifeng.com/blog/2014/0…
Hapi
Hapi is a Web framework for Node.js, which is a framework for building rich applications and services. Currently, Hapi V17 supports only Node V8.9.0 or later
- Understand: Node.js performance comparison of Hapi – Express-Restify-KOA
Hapi features
- Authentication and authorization: Built-in authentication and authorization scheme
- Caching: Provides client and server caching, catbox
- Route: built-in route
- Validation: Use Joi
- Cookies: Provides configuration options for handling Cookies
- Log: Built-in logging
- Error handling: BOOM
- Process monitoring: hapi plugin good
Requirements for using Hapi
- Install Node.js v8.9.0 or later
- Install the mongo
- Familiar with database concepts and JavaScript application knowledge
New changes to Hapi V17
-
The server.connection method has been removed and is now in use
const server = new Hapi.Server({ host: 'localhost', port: 3000 }) Copy the code
-
Enable or disable the service method is completely asynchronous without callback
try { await server.start() } catch (err) { console.log(err) } try { await server.stop() } catch (err) { console.log(err) } Copy the code
-
The reply() callback method is removed, and the response.hold() and Response.resume () methods are no longer available
// Previous const handler =function (request, reply) { return reply('ok'); }; // Now const handler =function (request, h) { return 'ok'; }; Copy the code
More examples of using h are as follows:
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) } Copy the code
-
Three request event types: REQUEST, request-interval, and request-error are combined into a single request event
-
Triggered methods like server.on, request.on, and Response.on are replaced with server.events.on(), request.events.on(), and response.events.on()
-
New request extensions:
server.ext('onPreAuth', (request, h) => {... }) server.ext('onCredentials', (request, h) => {... }) server.ext('onPostAuth', (request, h) => { … }) ] Copy the code
-
Replace config with options when defining routes
server.route({ method: 'POST', path: '/'Options: {... }})Copy the code
-
Plugins currently in use
exports.plugin = { register, name, version, multiple, dependencies, once, pkg } Copy the code
See GitHub’s full update log for more details
Topic: Build a simple API using Hapi
The CURD operation is provided in this example
- Get all demos – GET /demos
- Get one demo – GET /demo/11
- Create a demo – POST /demos
- Edit a demo – PUT /demos/11
- Delete a demo – DELETE /demos/11
A demo has the following properties:
- name
- age
1 Create project directory demo. The final structure is as follows:
Demo ├ ─ ─ package. Json ├ ─ ─ for server js ├ ─ ─ the gitignore (optional) └ ─ ─ the SRC ├ ├ ─ ─ controller | └ ─ ─ test. The js └ ─ ─ ─ models └ ─ ─ test. JsCopy the code
2 write the model
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');
Copy the code
Write the controllers
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 };
});
});
}
Copy the code
Write server. Js
'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)
}
})();
Copy the code
Test the API
Use the postman test at http://localhost:3000/demos
- demo
Adding authorization authentication
At present, there are a lot of steps, and you still need to register a platform, so I won’t go into details
reference
- GitHub:github.com/hapijs/hapi
- website: hapijs.com/
- Issue:github.com/hapijs/disc…
- developing-restful-apis-with-hapi v17
- Github.com/hapijs/hapi…