Hapi.js application architecture

I_Debug_Everything picture I_Debug_Everything · Mar 23, 2015 · Viewed 9.6k times · Source

I've been working on a hapi.js application and have the following architecture:

Database
  --Models
    --usermodel.js
    --anothermodel.js
Routes
  --private
    --controllers
      --ctrl1.js
      --ctrl2.js
    --validators
      --validatr1.js
      --validtr2.js
  --public
    --controllers
      --ctrl1.js
      --ctrl2.js
test
  --dbtest.js
  --functiontest.js
server.js

We adopted this structure when working with express, but I'm starting with a new application and was wondering if there are resources where I can find a better application structure? I've looked into the offical website for hapi and other resources but couldn't find anything interesting.

Any help appreciated. Thanks.

Answer

Matt Harrison picture Matt Harrison · Mar 26, 2015

The good thing about hapi is that it doesn't dictate to you how you should structure your apps. It's up to you, for whatever makes sense in your life. You could throw everything you have in a single index.js file and still use all of hapi features, but you're probably going to have a hard time reading/maintaining that hairball later.

If that structure above, that you've used before, still makes sense to your application, there's absolutely nothing stopping you using the same or a similar structure.

models - just non-hapi specific node modules that talk to your db

exports.getUser = function (id, callback) { 

    Db.get('users', id, callback) 
};

controllers - modules that export route handlers

var User = require('../models/user');

exports.showUserPage = function (request, reply) {

    User.getUser(request.params.id, function (err, user) {

        if (err) {
            throw err;
        }

        if (!user) {
            return reply('User not found').code(404)
        }

        reply.view('user', user);
    });
}

validators - modules that export joi schemas

exports.showUserPage = {
    params: {
        id: Joi.number().required()
    }
} 

server.js - where you glue all of that together

var Hapi = require('hapi');

var server = new Hapi.Server();
server.connection({ port: 7843 });

server.route({
    method: 'GET',
    path: '/users/{id}',
    handler: require('./controller/users').showUserPage,
    config: {
        validate: require('./validators/users').showUserPage
    }
});

server.start();

Plugins

You should probably take advantage of plugins, they let you split your application into logical chunks. You can still use the above structure but put it inside a plugin. New features you add later can go inside another plugin if they're unrelated (analytics, store etc). This lets you build a microservice architecture, where it's easy to scale out only the specific parts of your applications that need scaling.

What are other people doing?

If you're looking to change it just because you can, take a look at a few projects already built with hapi, and see how they're doing it: