Setting up a basic server in Hapi.js

This post is for those who understand the basics of NodeJS, Javascript, and MVC. It's also more suited for professionals who have made REST APIs in some other languages — such as Spring Boot, PHP — and are now seeking to do the same in NodeJS. This should be straightforward for a professional with 4+ years backend development experience.

For in-depth learning of Hapi.js concepts on asynchronous programming and industry case studies, check out the book Practical hapi.

Where to use NODE.JS REST APIs

This is a very popular debate and sometimes a more heated one. Personally, I find Node.JS more suitable for applications that are for small and medium businesses. JAVA Spring Boot is for more enterprise applications.

Tech stack more suited for SMBs

Small and medium business apps which need not scale up to the level of Enterprise Apps, generally fit in well with an all in all Javascript Stack – MEAN Stack. In fact, that was one primary reason for NodeJS being popular – a good fit with Angular.JS

Quick fetch and show results

Sometimes, your application doesn't need to rely on ORMs like Sequelize, – NodeJS might suit your purpose. NodeJS and the NPM ecosystem offer a wide array of tools that help in making lite weight data retrieval programs. Coding a full web app in JAVA EE is often overkill when developers want smaller, lightweight solutions for an everyday technology market.

Built-in server setup

Node.JS is a server in itself. PHP and JAVA require external Tomcat and Apache servers. For me, integration of the server into the application was well suited for a micro-services project where every application has its own server. This became a very important consideration for building clustered applications.

Everything in JavaScript 

A full-stack javascript tech stack is especially attractive for smaller web apps because many developers already know JavaScript and it can save much cognitive overhead to use it full-stack. JavaScript is a requirement for frontend web coding. Before Node.js gained widespread adoption it was common to have separate frontend and backend languages. This added engineering overhead as developers would have to cognitively switch from one language to another. Hiring overhead was also added looking for both frontend and backend developers.

Initializing Hapi at the CLI

Although we don't cover the installation of Node.JS in-depth, here is the most comprehensive guide to its download and installation. It covers every possible manner that might work on your OS. The website also covers Node.JS docs in detail if you so prefer, and is a must for anyone looking for a transition to the world of Node.JS

Installing Node.js via package manager

The command that I used:

yum install nodejs12

The number12 can be nodejs8 and so on. It's for the version.

For Win users – download NodeJS from here: https://nodejs.org/en/

Check your node installation and off you go!

Before building a fully blown RESTful API, we set up the server environment. Once you’ve installed Node, create a directory, say: polling-api and enter it on the CLI. Type:

npm init

Just enter all descriptors like name, version, description, author and confirm when it asks you – "Is this ok?" By default, one of those descriptors is index.js – which is the entry point of your app. Change it to a file, that suits you. Call it – app.js or server.js, or whatever you might wish.

This installs all your node dependencies. Check your folder again. You should have a package.json and node modules folder installed for you.

Next type:

npm install @hapi/hapi

This installs all hapi.js framework dependencies. The save option adds it to the package.json file. Keep noting the changes in the folder structure and the package.json file when you run npm for installing and saving modules.

Next, create a file called server.js. We called it our entry point, during setup.

Check your package.json file, it should say: “main”: “server.js”

Note: We're using v12.14.1 for node, Node.js 7.6+ ships with official support for async/await enabled by default and better performance on low-memory devices.

Setting up the server – server.js

'use strict';
const Hapi = require('hapi');
const server = Hapi.server({
        port: 3000,
        host: 'localhost'
    });
const init = async () => {
   await server.start();
    console.log('Server running on %s', server.info.uri);
server.route({
    method:'GET',
    path:'/home',
    handler: (request, h) => {
            return '<h3>Hello Kanika!</h3>';
        }
});
server.route({
    method:'GET',
    path:'/home/{name}',
    handler: (request, h) => {
            return `Hello ${request.params.name}!`;
        }
});
}; init();

Explaining server.js

The purpose of “use strict” is to indicate that the code should be executed in “strict mode”.

With strict mode, you can not, for example, use undeclared variables.

All modern browsers support “use strict” except Internet Explorer 9 and lower

Creating The Server

const server = Hapi.server({
        port: 3000,
        host: 'localhost'
    });

With Hapi.js v17+ you can create the server without a connection method on the server object. 

Starting the server is a clean job, wrapping up the server start code in an async() function with an await keyword.

const init = async () => {
await server.start();   ….       }
});
init();

Assuming that you have the package.json setup(with npm init as described in the pages above), and your node server is started already with the following command: npm start, you can now, test the server URL with:

http://localhost:3000/

On the browser, you'd get an error: {“statusCode”:404,”error”:”Not Found”,”message”:”Not Found”}

This is because you needed a route to be able to access the server files on a browser. Explained next.

Routing

Note the following routing methods:

server.route({    method:'GET',    path:'/home',    handler: (request, h) => {         return '<h3>Hello Kanika!</h3>';        }});

http://localhost:3000/home

server.route({    method:'GET',    path:'/home/{name}',    handler: (request, h) => {     return `Hello ${request.params.name}!`;        }});

http://localhost:3000/home/Brad

Hit the above URLs in your browser, and see the result. The first gives Hello Kanika! while the second gives Hello Brad!

Understand the following from the docs. We've given a brief here.

From the docs:

Method param

The method param can be any valid HTTP method, array of HTTP methods, or an asterisk to allow any method.

Path param

The path parameter defines the path including parameters. It can contain optional parameters, numbered parameters, and even wildcards. For more details, see the routing tutorial.

Handler param

The handler function performs the main business logic of the route and sets the response. The handler must return a value, a promise, or throw an error.

Response

The response can return a String value, request parameters and the like.

Up to here, we made a simple Hapi app. 

Role of the Event Loop In loading dependencies

Node applications then enter the Event Loop, responding to incoming client requests by executing the appropriate callbacks and loading a dependency as registered. 

Codnostic is creating a book published by Apress, for all solutions in practical Hapi.

Until then, we suggest you take the following learning path:

Learning path for Hapi

Make sure you know the basics of HTTP, REST APIs, and Node.js. Understanding Hapi won't make sense without any of these.

Make sure you know the basics of Javascript and asynchronous programming. We highly recommend:

https://javascript.info/

After getting packed with the server.js file, understand the following for an industry level project:

  • Organizing routes
  • Authentication in Hapi
  • Organizing your application
  • Validation in Hapi – with joi
  • Plugins in Hapi
  • Database connectivity
  • ORMs – sequelize
  • Testing and logging