Hapi.js is a small Node framework for developing back end web apps.
In this article, we’ll look at how to create back end apps with Hapi.js.
File Utility
We can generate a file path from path segments with the @hapi/file
module.
For example, we can write:
const Hapi = require('@hapi/hapi');
const file = require('@hapi/file');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
const fileName = file.uniqueFilename('/root', '.txt');
return fileName
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call the file.uniqueFilename
method to create a unique file name.
We should get something like:
/root/1604965754941-1144-2fbcec5c8927e564.txt
returned as the response.
Compose Different Server Components
We can use the @hapi/glue
module to compose different server components.
To use it, we write:
index.js
const Hapi = require('@hapi/hapi');
const Glue = require('@hapi/glue');
const manifest = {
server: {
port: 3000,
host: '0.0.0.0'
},
register: {
plugins: [
{
plugin: require('./my-plugin'),
options: {
uglify: true
}
},
],
}
};
const options = {
relativeTo: __dirname
};
const init = async () => {
const server = await Glue.compose(manifest, options);
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return 'hello'
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
my-plugin.js
const myPlugin = {
name: 'myPlugin',
version: '1.0.0',
async register (server, options) {
server.route({
method: 'GET',
path: '/test',
handler (request, h) {
return 'hello, world';
}
});
}
};
module.exports = myPlugin
We created a plugin with one route within the my-plugin.js
file.
Then in index.js
, we have our manifest
object with the server options.
register
is a property with the plugin properties inside.
The plugins
array has an array of plugins we want to register.
options
has extra options we want to set for our server.
Then we compose everything together with the Glue.compose
method.
It returns the Hapi server
object which we can use to add more routes with the server.route
method.
Process Monitor
We can add a simple process monitor to our Hapi app with the @hapi/good
module.
To add it, we write:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
await server.register({
plugin: require('@hapi/good'),
options: {
ops: {
interval: 1000
},
reporters: {
myConsoleReporter: [
{
module: '@hapi/good-squeeze',
name: 'Squeeze',
args: [{ log: '*', response: '*', ops: '*' }]
},
{
module: '@hapi/good-console'
},
'stdout'
]
}
}
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return 'hello'
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We add the reporters
property to add a logger for monitoring resource usage.
We add the @hapi/good-squeeze
module to add the items to log with the args
array.
log
has the timestamp, response
has the HTTP response returned, and ops
has the resource usage.
The @hapi/good-console
lets us log the numbers to the console.
Conclusion
We can add various modules to our Hapi app to monitor resource usage, generate file names, and compose server components.