hapi — Create Your Own Custom Plugin

This guide continues on extending your server’s functionality with the help of plugins. Within the previous tutorial, you’ve learned how to register a plugin to your hapi server instance and with that increase the servers feature set. Also, we’ve described hapi’s efficient plugin system and the unwritten best practice to split your application logic into various small, isolated modules.

Now it’s time to learn how to write your own plugin that adds your desired functionality to hapi. Due to the extensiveness of this hapi series, have a look at the series outline below to find other interesting guides.

hapi Series Overview

Write a Plugin

Based on the fact that it’s recommended to extend your servers functionality using plugins, there should be a convenient way to write your own, custom one. Essentially, a plugin is an object with a register property that returns a function with the signature function (server, options, next). Further, the register function has an attributes object that contains meta data about your plugin to provide some extra data for hapi. The attributes can be something like name and version.

var myplugin = {  
  register: function (server, options, next) {
    // add functionality -> we’ll do that in the section below

    // call next() to signal hapi that your plugin has done the job
    next()
  }
}

myplugin.register.attributes = {  
  name: 'myplugin',
  version: '1.0.0'
}

module.exports = myplugin  

We’ve mentioned that the register function of your plugin takes three arguments server, options and next. Let’s review each of them: server is the reference instance to your server that you’re going to extend (like adding route handlers to render views or reply in other formats) or just use it to call server methods. The options object contains plugin specific configuration that is required to run your plugin appropriately.

At last, you have to call next to signal hapi that you’ve registered or configured the desired functionality and your plugin is done. You can also call asynchronous methods while registering your plugin. Just use the next function at the right spot, like within the callback or promise.

Up to this point, you’ve seen the basics of how to write a custom plugin. Let’s make things more approachable and add a route handler within our custom plugin.

Add Functionality Within Your Custom Plugin

Within the getting started tutorial of this hapi series, we’ve created a basic hapi server that sends a Hello Future Studio! message when calling the default / route. The code below illustrates the mentioned server code:

var Hapi = require('hapi')

// create new server instance
var server = new Hapi.Server()

// add server’s connection information
server.connection({  
  host: 'localhost',
  port: 3000
})

// add “hello world” route
server.route({  
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply('Hello Future Studio!')
  }
})

// start your server
server.start(function (err) {  
  if (err) {
    throw err
  }

  console.log('Server running at: ' + server.info.uri)
})

In the following, you’ll refactor the shown code above and create your own plugin that registers the route handler and responds with the Hello Future Studio! message. Alright, let’s get going.

First, create a file called base-route.js that will add a GET route at path / and replies with the given message.

base-route.js

var baseRoutes = {  
  register: function (server, options, next) {
    // add “hello world” route
    server.route({
      method: 'GET',
      path: '/',
      handler: function (request, reply) {
        reply('Hello Future Studio!')
      }
    })

    next()
  }
}

baseRoutes.register.attributes = {  
  name: 'base-routes',
  version: '1.0.0'
}

module.exports = baseRoutes  

As you can see, we’re extending the server instance by registering the route. Of course, you could enhance the route’s handler method with additional functionality. For now, let’s just focus on the refactoring part and create your first plugin. Because the server.route() method is a synchronous operation, we can add the next call right after the route registration.

Within the servers.js file, you need to remove the previously defined route registration and register the newly created plugin. If you need to recap on how to load plugins to your hapi server, have a look at the linked tutorial.

server.js

var Hapi = require('hapi')

// create new server instance
var server = new Hapi.Server()

// add server’s connection information
server.connection({  
  host: 'localhost',
  port: 3000
})

// register plugins to server instance
server.register({  
  register: require('./base-route')
})

// start your server
server.start(function (err) {  
  if (err) {
    throw err
  }

  console.log('Server running at: ' + server.info.uri)
})

Within the snippet above, you can see the call of server.register() to add your plugin to the hapi server instance and with that, add the handler to respond any GET requests on route path /. We aren’t using any plugin options, that’s why we don’t pass them during the register phase.

To check if everything went smooth, start your server instance and open the browser or use curl to call localhost:3000. You should receive the Hello Future Studio! message.

Outlook

This tutorial walked you through the fundamentals on how to create your custom hapi plugin. You’ve also created your own plugin that registers a route handler to respond a request with a message. Use this basis and extend your plugins to provide the desired functionality and extend the server capabilities.

Within the next guide, you’ll get a grasp on how to render and serve beautiful views.

If you’ve any question, please let us know in the comments below or reach out at Twitter, @futurestud_io.

Enjoy coding & make it rock!

Explore the Library

Find interesting tutorials and solutions for your problems.