hapijs / hapi

The Simple, Secure Framework Developers Trust
https://hapi.dev
Other
14.61k stars 1.34k forks source link

Forward route to another route? #2487

Closed hems closed 9 years ago

hems commented 9 years ago

At the moment i have a "catch all" route like path : '/{page*}' then on this route i must check if this is a page template or a user page.

At the moment this route has an "if" conditional, which directs it to the right render function.

But in an ideal world, i believe would be cleaner to have 1 route for template and 1 route for user page, and then on my "catch all" route, i can just check which kind of page it is and then "forward" it to the correct route.

something like this pseudo code:

handler: function ( request, reply ) {
  url = request.url.href

  if url is user_route then return request.forward( "/user_route" )

  if url is template_route then return request.forward( "/template_route" )

  return reply( "Page not found" ).code( 404 )
}

Would that be possible ?

danielb2 commented 9 years ago

Can you give an example of what constitutes a user_route and a template_route? It's difficult to tell if it's possible without knowing. The routes would have to begin with something to distinguish them as such.

For example /user/{path*} and /template/{path*} would work, but I suspect it's not like that. Because of how hapi routes are designed, there can't be any overlap of routes. Iow, you can't do something like

/users/{path*} and /{blah*}/template. However, what you can do is /{blah*3}/template if you know the number of segments, and that number is constant

hems commented 9 years ago

Actually i just realised i have a solution, but i still wonder what would be the " hapi js way"

see this pseudo code:

// my "catch_all"route"
user_route = require( "./user_route" )
template_route = require( "./template_route" )

handler: function ( request, reply ) {
  url = request.url.href

  if url is 'some_url_i_know_its_a_user' then return user_route.handler( request, reply );

  if url is 'some_url_i_know_its_a_template' then return template_route.handler( "/template_route" )

  return reply( "Page not found" ).code( 404 )
}
hems commented 9 years ago

answering you question, "user_route" and "template_route" is something that i discover using an assyncronous method.

if the template exists on disk, it's a template route.

if doesn't exist, fetch a user from the database.

if the user doesn't exist, it's 404.

I do this for the sake of pretty urls at the cost of this roundtrip on all requests ( which the result will be cached later on the process ).

An improvement would be to create routes for all templates from disk dynamically, so then i know it will be either user or 404, avoiding checking if the template exists on disk, which means i could actually close this issue and don't bother you guys ( :

devinivy commented 9 years ago

This may be what you're looking for: Request#setUrl.

hems commented 9 years ago

@devinivy perfect, so onRequest i should parse the URL myself and re-route it?

there is no way of doing that from inside a route?

devinivy commented 9 years ago

Correct!

hems commented 9 years ago

@devinivy last question: is there an easy way to use hapi.js url parser on onRequest ?

ps: thanks for the clarification

devinivy commented 9 years ago

Sure! The router has it's own project here: https://github.com/hapijs/call. This will get you a start:

var Call = require('call');

var Router = new Call.Router({});
var pathInfo = Router.analyze('/some/{path*}');
arb commented 9 years ago

@hems I would suggest creating the routes dynamically before the server starts like you said in an here. Either that or change your logic to use route parameters so you know ahead of time if it's a template or not. The path you are going down is inefficient. If you are the one creating the server, how do you not know if a user/template exists or not? Also, do you have the same route set up to serve two purposes? If so, that is bad design. 1 route => 1 predictable resource.

hems commented 9 years ago

@arb i'm aware of that and was asking about the router for learning purposes.

indeed the best solution is to create the template routes dynamically.

( :

thanks for your insights guys!

have a nice week!

:8ball: