Mastering Server-Side Development with Hapi.js
Written on
Chapter 1: Introduction to Hapi.js
Hapi.js is a lightweight framework for Node.js, designed specifically for building back-end web applications. In this guide, we will delve into how to effectively create back-end applications using Hapi.js.
Section 1.1: Implementing View Helpers
We can enhance our application by incorporating view helpers. For instance, consider the following code snippet:
const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const context = {
title: 'My personal site'
};
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0',
debug: { request: ['error'] }
});
await server.register(require('@hapi/vision'));
server.views({
engines: {
html: {
module: require('handlebars'),
compileMode: 'sync'
},
},
relativeTo: __dirname,
path: 'templates',
helpersPath: './templates/helpers',
context
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return h.view('index');}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
In this example, we create a context with a title and set up a Hapi server. When users access the root URL, they receive an HTML view rendered with the context provided.
Next, we can define a helper function in templates/helpers/fortunes.js:
module.exports = () => {
const fortunes = [
'Wanna buy a duck?',
'Say no, then negotiate.',
'Time and tide wait for no man.',
'To teach is to learn.',
'Never ask the barber if you need a haircut.',
'You will forget that you ever knew me.',
'You will be run over by a beer truck.',
'Fortune favors the lucky.',
'Have a nice day!'
];
const x = Math.floor(Math.random() * fortunes.length);
return fortunes[x];
};
This function randomly selects a fortune to display. In index.html, we use the helper by interpolating its value: {{fortune}}. With this setup, each visit to the root page presents a different fortune.
Section 1.2: Utilizing Layouts
We can organize our layouts into separate files. Here's how we can define a layout in our server setup:
const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const context = {
title: 'My personal site'
};
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0',
debug: { request: ['error'] }
});
await server.register(require('@hapi/vision'));
server.views({
engines: {
html: {
module: require('handlebars'),
compileMode: 'sync'
},
},
relativeTo: __dirname,
path: 'templates',
layout: true,
layoutPath: 'templates/layout',
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return h.view('index');}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
In this configuration, we enable layout files by setting layout to true and specifying the layoutPath. The layout file, layout.html, can be structured to display the content dynamically:
{{{content}}}
In templates/index.html, we define the content that will be rendered within this layout.
Chapter 2: Customizing Layouts Per View
We also have the flexibility to assign different layouts for specific views. For example, we can modify our route handler as follows:
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return h.view('index', null, { layout: 'another_layout' });}
});
In this case, we specify another_layout to be used when rendering the index view.
The first video, titled "Hapi.js Framework Crash Course - YouTube," provides a comprehensive introduction to Hapi.js and its functionalities.
The second video, "Node.js App From Scratch | Express, MongoDB & Google OAuth - YouTube," dives into building a complete Node.js application, showcasing practical use cases with Hapi.js.
Conclusion
In summary, Hapi.js enables the rendering of layouts and helpers within views, making it a powerful tool for back-end development. By leveraging these features, developers can create dynamic and engaging web applications.