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.
Routing
We can add routes easily to our Hapi app.
For example, we can write:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: '0.0.0.0',
});
server.route({
method: 'GET',
path: '/',
handler (request, h) {
return 'Hello World!';
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
to add a simple route with:
server.route({
method: 'GET',
path: '/',
handler(request, h) {
return 'Hello World!';
}
});
The method
has the request method the route accepts.
path
has the route path.
handler
has the route handler to handle the request.
request
has the request data.
One route can handle multiple request methods.
For example, we can write:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: '0.0.0.0',
});
server.route({
method: ['PUT', 'POST'],
path: '/',
handler (request, h) {
return 'Hello World!';
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We have a route that handles both 'PUT'
and 'POST'
requests.
Path
A route can accept URL parameters if we put a parameter placeholder in our route path.
For example, we can write:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: '0.0.0.0',
});
server.route({
method: 'GET',
path: '/hello/{user}',
handler: function (request, h) {
return `Hello ${request.params.user}!`;
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We have a route that takes the user
request parameter.
Then we can get the route parameter value from the request.params.user
property.
Now if we make a GET request to the /hello/bob
route, we get Hello bob!
.
The parameter value isn’t escaped by default. We can escape the string that’s passed by writing:
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: '0.0.0.0',
});
server.route({
method: 'GET',
path: '/hello/{user}',
handler: function (request, h) {
return `Hello ${Hoek.escapeHtml(request.params.user)}!`;
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We required the @hapi/hoek
package and then call Hapi.escapeHtml
on the request.params.user
string to escape it.
This will prevent any cross-site scripting attacks since any code strings will be sanitized.
Optional Parameters
We can make a parameter optional with the ?
.
For instance, we can write:
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: '0.0.0.0',
});
server.route({
method: 'GET',
path: '/hello/{user?}',
handler: function (request, h) {
const user = request.params.user || 'anonymous'
return `Hello ${user}!`;
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We have {user?}
in the route string to make the user
parameter optional.
Then when we go to /hello
, we get Hello anonymous!
And when we go to /hello/bob
, we get Hello bob!
.
Conclusion
We can add various kinds of routes with Hapi.