Hapi 17 was recently released, and brings an exciting change — in an effort to drive adoption of async/await, the
entire codebase replaced callbacks with the newer language feature.

This makes for some changes to how you configure your application. The intent of this post is to get you up and
running as quickly as possible.

Installation

npm i --save hapi

or,

yarn add hapi

Setting up your server

constHapi=require("hapi");// define some constants to make life easierconstDEFAULT_HOST="localhost";constDEFAULT_PORT=3000;constRADIX=10;

You can change the default host and port to your liking, this is just an example of some common defaults.

Major change — no more connections, you define 1 server which equals 1 connection. Only relevant if you used to have (for instance)
an API server and a UI server defined in one place previously (using server.connection API - that’s gone now).

Also, Hapi.server is no longer a class-like structure so no more new keyword - just use the Hapi.server method directly:

We use the HOST and PORT values passed in via an environment variable (common method used in cloud server hosting) and fall
back to our previously defined default host/port if no such environment variable is set.

Note that Hapi expects port to be an integer, so use parseInt to make sure the value passed from the environment is correct type.

Enclosing in an async function

The methods to register plugins and start your server are asynchronous, and you use the await keyword to wait for their return value.
For it to be valid syntactically to use the await keyword, you must be within an async function — so we wrap everything in a main
function, which you can name whatever you like:

constmyServer=async()=>{};myServer();// don't forget to call it

We want to make sure to call the function, or nothing will happen — so we add the call up front so we don’t forget.

Error-handling

If Hapi can’t start, or can’t register a plugin, it throws an error. We should therefore be ready to handle such an error,
so we wrap in a try..catch:

In your catch block, at the very least you should log something to the console so you have an indication why it failed -
otherwise it will just silently exit.

Registering plugins

Inside the try block above, we register any plugins we may need.

This could be Hapi official plugins for things like Logging, Static File serving, caching, exception handling, etc.

But also, it’s a good idea to modularize your web application in to the plugin approach too (so, a plugin you define for
everything to do with one piece of functionality you provide, another plugin for a separate piece of functionality, etc).

For now, let’s assume we’re going to be building an API that has 1 route, that returns “Hello World”, so we’re going to
make that a plugin later in this post.

We will register it like so:

try{// this is the try block from aboveawaitserver.register(api);}catch(err){// ...etc

In server.register, we can pass a single object (1 plugin) or an array of objects (multiple plugins).

And we’ll require it at the top of the file:

constHapi=require("hapi");constapi=require("./api");

Starting your server

try{// this is the try block from aboveawaitserver.register(api);awaitserver.start();console.log(`Hapi server running at ${server.info.uri}`);}catch(err){// ...etc

This starts the server after registering your plugin, then logs out to the console the URI it started up on.

Sharing properties within your app

The app property on the object you pass to Hapi.server is optional, but is a great place to store variables that
you will use throughout your application.

Whatever is set on that object will be available on every instance of server being passed (think: Plugins, Extension
Points) and every time you have a request object (think: Route Handlers, etc).

For example, if you have app: { foo: "bar" } then in your route handler, given:

Defining a plugin

So to contain your functionality of an API route that replies “Hello, World” you create the file, with a path relative to your
file above of ./api/index.js (so if your server is at YOUR_DIRECTORY/server.js then this one will be YOUR_DIRECTORY/api/index.js: