hapi – Building applications
and services in Node.js

What's hapi?

Web application framework for Node.js
Developed by Walmart Labs

(You may have heard of #nodebf.)

Core concepts

  • Configuration over code
  • Modularity and maintainability

Production ready ecosystem

  • Validation: Joi
  • Caching: Catbox (Memory, Redis, MongoDB, Memcached, Riak, S3, …)
  • Authentication: bell, hapi-auth-*
  • Logging/Monitoring: Good (UDP, HTTP, File, Console, …)
  • Unit-Testing/Code Coverage: Lab
  • API documentation generator: lout

Absolutely lovely,
super helpful community. <3

How to get started?


var hapi = require('hapi');
var server = new hapi.Server();

server.connection({ port: 8000 });
server.start(function (err) {
    console.log('server started @ ' + server.info.uri);
});
                    

Routing


server.route({
    method: 'GET',
    path: '/hello/{name}',
    handler: function (request, reply) {
        reply('Hello ' + request.params.name + '!');
    }
});
                    

reply handles String, Object, Buffer and Stream responses.

Objects are serialized as JSON and are automatically sent with the right content type.

Further possibilities

reply.file()
reply.directory()
reply.view()
reply.proxy()
                    

server.decorate('reply', 'success', function () {
    return this.response({ status: 'ok' });
});
reply.success();
                    

Proxy example


var mapper = function (request, callback) {
    callback(null, 'http://www.google.com/search?q=' + request.params.term);
};

server.route({
    method: 'GET',
    path: '/search/{term}',
    handler: { proxy: { mapUri: mapper } }
});
                    

Validation


var Joi = require('joi');
                    

server.route({
    method: 'GET',
    path: '/hello/{name}',
    handler: function (request, reply) {
        reply('Hello ' + request.params.name + '!');
    },
                    
    options: {
        validate: {
            params: { // 'headers', 'query', 'params', 'payload', and 'auth'
                name: Joi.string().min(3).max(10);
            }
        }
    }               

});
                    

Caching (Browser side)


server.route({
    method: 'GET',
    path: '/hello/{name}',
    handler: function (request, reply) {
        reply('Hello ' + request.params.name + '!');
    },
                    
    options: {
        // Cache-Control: public, max-age=3600000
        cache: {
            privacy   : 'public',
            expiresIn : 60 * 60 * 1000 // 1 hour
        }
    }               

});
                    

Caching (Server side)


server.method(
    name: 'liftHeavyStuff',
    method: function (arg1, …, argN, next) {
        // …
        next(null, result);
    },
    options: { cache: { expiresIn: 60 * 60 * 1000 } }
);
                    

// Inside a route handler
server.methods.liftHeavyStuff('foo', function(err, result) { /* … */ });
                    

Plugins


exports.register = function (server, options, next) {
    // …
};
                    

exports.register.attributes = {
    // either
    name: 'my plugin',
    version : '0.1.0'

    // or
    pkg: require('./package.json');
};
                    

Everything can be a plugin

  • Server methods
  • Authentication strategies
  • Handlers during request lifecycle (aka "middleware")
  • Routes and partial applications

hapi allows very flexible, yet focused development,
ideal for teams working on different parts of the application.

Resources

hapi coding!

Frederic Hemberger
Twitter
@fhemberger
GitHub
fhemberger
Web
frederic-hemberger.de