Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically adding a route in Play2.0

In play 1.2.X we could do

Router.addRoute("GET", "/somePath", "controller.methodName");

I'm writing a module that adds a "route" that will be handled by a controller in the module. It's a OAuth handler and want to make it easy for users to not have to deal with the OAuth handshake etc.

How can I do this in Play 2.0?

like image 427
Anand B Narasimhan Avatar asked Apr 12 '12 01:04

Anand B Narasimhan


3 Answers

You can't add programmatically to the Routes object, but you can intercept web requests and handle them yourself by overriding GlobalSettings.onRouteRequest. For example:

override def onRouteRequest(request: RequestHeader): Option[Handler] = {
  //do our own path matching first - otherwise pass it onto play.
  request.path match {
    case "/injectedRoute" => Some(controllers.Application.customRoute)
    case _ => Play.maybeApplication.flatMap(_.routes.flatMap {
      router =>
      router.handlerFor(request)
    })
  }
}

I've no idea if this is the recommended approach, but it works for me. Here's a sample on github: https://github.com/edeustace/play-injected-routes-example

like image 64
ed. Avatar answered Sep 21 '22 07:09

ed.


I am not sure you can.

The concept of Play 2.0 was to focus on type safety, which includes the routes file. The routes file is now compiled, rather than interpreted at run time. If you look at the code for the routes file, it generates a scala class from the routes file itself. Therefore, runtime manipulation would simply be ignored.

Unfortunately it looks as though your routes must be defined in the routes file, unless you are willing to intercept the http requests to check for specific routes yourself, which is what the /@documentation links appear to do in the ApplicationProvider scala class.

Also see this bug post https://play.lighthouseapp.com/projects/82401/tickets/12-support-multiple-routes-file-and-inclusion

like image 37
Codemwnci Avatar answered Sep 20 '22 07:09

Codemwnci


You can add a generic route in your routes file (at the end of file as its priority would be assessed on the basis of its location of declaration)

GET     /:page  controllers.Application.showPage(page)

Put your logic which you want to execute on runtime in controller class

public static Result showPage(String page){

    if(page.contains("abc"){
      .....
    } else {
      //return 404
    }
}

I'm not sure if it would fit into your requirement but in most of the scenarios it will suffice.

like image 44
sumitarora Avatar answered Sep 19 '22 07:09

sumitarora