HapiJS global path prefix

I was able to get it working for all routes with

var server = new Hapi.Server()
...
server.realm.modifiers.route.prefix = '/v0'
server.route(...)

If you put your API routing logic inside a Hapi plugin, say ./api.js:

exports.register = function (server, options, next) {

    server.route({
        method: 'GET',
        path: '/hello',
        handler: function (request, reply) {
            reply('World');
        }
    });

    next();

};

exports.register.attributes = {
    name: 'api',
    version: '0.0.0'
};

You register the plugin with a server and pass an optional route prefix, which will be prepended to all your routes inside the plugin:

var Hapi = require('hapi');

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

server.register({
    register: require('./api.js')
}, {
    routes: {
        prefix: '/v0'
    }
},
function(err) {

    if (err) {
        throw err;
    }

    server.start(function() {
        console.log('Server running on', server.info.uri)
    })

});

You can verify this works by starting the server and visiting http://localhost:3000/v0/hello.


For Hapi 19, 20 ... you can simply modify the route with map path before you register it.

// Example route
const routes = [
    {
        method: 'GET',
        path: '/test',
        handler: function (request) {
            return {
                status: 'success'
                };
            }
    }
];

// transform /test -> /api/test
routes.map((r) => {
    r.path = `/api${r.path}`;
    return null;
});


// Register
server.route([
    ...routes
]);

Matt Harrisson's answer is the hapi way to do it using plugins.

Alternatively if you don't want to create a plugin just to add a prefix, you can by hand, add the prefix to all your routes.

For instance I went for something like this:

  var PREFIX = '/v0';
  var routes = [/* array with all your root */];

  var prefixize = function (route) {  route.path = PREFIX + route.path;return route; }
  server.route(routes.map(prefixize));

Good point is that with something like this your can perform express-like mounting. ex:

 var prefixize = function (prefix, route) {  route.path = prefix + route.path;return route; }

server.route(adminRoutes.map(prefixize.bind({}, "/admin"))); //currying.
server.route(apiRoutes.map(prefixize.bind({}, "/api")));