Mastering Hapi.js: Building Server-Side Applications Efficiently
Written on
Introduction to Hapi.js
Hapi.js is a lightweight framework for Node.js that facilitates the creation of backend web applications. In this article, we will explore how to effectively develop backend applications using Hapi.js.
File Handling with @hapi/file
To generate file paths from segments, the @hapi/file module is utilized. Below is an example of how to implement it:
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();
The method file.uniqueFilename helps create a distinct file name, resulting in an output similar to /root/1604965754941-1144-2fbcec5c8927e564.txt.
In this video, learn how to serve static files using Hapi.js, enabling efficient file handling.
Composing Server Components
Utilizing the @hapi/glue module allows for the composition of various server components. Here’s how to set it up:
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();
In the above example, a plugin is created within my-plugin.js, which adds a new route. The manifest object in index.js includes server settings, and the plugins array lists the plugins to register.
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;
The Glue.compose method combines all components, returning a Hapi server instance that can accept additional routes.
Process Monitoring with @hapi/good
Integrating a basic process monitor into your Hapi application can be achieved using the @hapi/good module. Below is an implementation example:
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();
This setup allows you to monitor resource utilization and log various server activities. The @hapi/good-squeeze module specifies what to log, while @hapi/good-console outputs logs to the console.
This video walks you through starting your server with Hapi.js, providing essential insights for beginners.
Conclusion
By utilizing various modules within Hapi.js, developers can efficiently manage file generation, compose server components, and monitor application processes, enhancing the overall development experience.