Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hapi.js - 404 route VS static files route

I'm trying to migrate my Express app to hapi.js, and I having trouble with my routes. I just want 2 GET : my index '/', and everything that is not '/' to redirect to '/'.

Using Express I had this:

// static files
app.use(express.static(__dirname + '/public'));

// index route
app.get('/', function (req, res) { 
  // whatever
}

// everything that is not /
app.get('*', function(req, res) { 
  res.redirect('/');
});

I have issues with hapi.js to get the same behaviour. My "static road" looks like this:

server.route({
  method: 'GET',
  path: '/{path*}',
  handler: {
    directory: {
      path: 'public',
      listing: false
    }
  }
});

and my "404 road" would be:

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

and I get this error:

Error: New route /{path*} conflicts with existing /{path*}

How can I resolve this?

like image 421
Thibaud Tallon Avatar asked Mar 27 '15 16:03

Thibaud Tallon


People also ask

How to handle 404 errors in Hapi app?

To handle 404 errors in your hapi app, add a single route that represents a last resort. This route will match all route paths that didn’t fit to any other route in your server. The defined route handler will be applied to GET and POST requests. If you need to handle any other method, add it to the list.

How do I define a route in Hapi?

When defining a route in hapi, you need three basic elements: the path, the method, and a handler. These are passed to your server as an object, and can be as simple as the following:

What is the route handler in Hapi?

That’s all the magic :) This route handler will catch all routes that don’t match any of your other routes within your hapi server. Because this route has the least restrictions for any paths and parameters, it’ll be called last by hapi. Of course the most interesting part is the result.

Can I serve static files in Hapi?

If you’re serving HTML views to your client, you might want to display images or provide JavaScript files to enhance the client side functionality. This guide walks you through the setup of hapi to serve static files like images, JavaScript files, compressed archives ( .zip, .tar, etc.).


1 Answers

You're defining 2 routes with the same method and path, which is a conflict as far as hapi's router is concerned. That's why you're getting the error.

If a file isn't found by the directory handler, it will respond with a 404 error by default.

What you can do is intercept this with an onPreReponse handler, which checks if the response is an error response (a Boom object), and if so respond however you wish. In your case by redirecting to /:

var Hapi = require('hapi');

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

server.route([{
        method: 'GET',
        path: '/',
        handler: function (request, reply) {

            reply('Welcome home!');
        }
    }, {
        method: 'GET',
        path: '/{p*}',
        handler: {
            directory: {
                path: 'public',
                listing: false
            }
        }
    }
]);

server.ext('onPreResponse', function (request, reply) {

    if (request.response.isBoom) {
        // Inspect the response here, perhaps see if it's a 404?
        return reply.redirect('/');
    }

    return reply.continue();
});

    
server.start(function () {
    console.log('Started server');
});

Recommended reading:

  • hapi's request lifecycle and extension points: http://hapijs.com/api#request-lifecycle
  • The response object: http://hapijs.com/api#response-object
like image 129
Matt Harrison Avatar answered Sep 29 '22 22:09

Matt Harrison