Is there a standard way to get all routes / paths valid within a play application 2.6.x?

275 views
Skip to first unread message

deng air

unread,
Oct 7, 2017, 10:06:53 PM10/7/17
to Play Framework
I could get a List of tuples of method, path and action strings in Play 2.5.x by
Play.current().routes().asJava().documentation()

, but Play.current().routes() is missing in Play 2.6.x. 

Greg Methvin

unread,
Oct 8, 2017, 1:09:26 AM10/8/17
to play-framework
You can inject a play.routing.Router and call its documentation method.

Both Play.current and Application#routes were deprecated in 2.5.x as well.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/5b5ab819-9e20-45fc-98a0-570d8e59cdc8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

Michael Slinn

unread,
Oct 10, 2017, 1:37:00 PM10/10/17
to Play Framework
What did I do wrong? I tried injecting a Router, and then a RoutesProvider, with the same result.

class AuthenticationController @Inject()(
  mcc: MessagesControllerComponents,
  routesProvider: RoutesProvider
)(implicit
  ec: ExecutionContext,
  webJarsUtil: org.webjars.play.WebJarsUtil
) extends MessagesAbstractController(mcc) with I18nSupport {
  val routes: Seq[(String, String, String)] = routesProvider.get.documentation
  routes.foreach { case (controllerMethod, method, path) =>
    println(s"controllerMethod: $controllerMethod")
    println(s"method: $method")
    println(s"path: $path")
  }
}


The error is:

ProvisionException: Unable to provision, see the following errors:

1) Found a circular dependency involving router.Routes, and circular dependencies are disabled.
  while locating router.Routes
  at controllers.authentication.AuthenticationController.<init>(AuthenticationController.scala:102)
  while locating controllers.authentication.AuthenticationController
    for the 4th parameter of router.Routes.<init>(Routes.scala:40)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application



Thanks,

Mike

Greg Methvin

unread,
Oct 10, 2017, 3:53:31 PM10/10/17
to play-framework
Try injecting Provider[Router], and make sure all your references to it are lazy (lazy val or def).

Since Play's router depends on the controllers you need to use a provider to break the circular dependency. RoutesProvider won't work since it's a concrete class. What you want is for Guice to create you a provider instance that lazily provides the router.

You can write something like:

class AuthenticationController @Inject()(routesProvider: Provider[Router]) {
  lazy val routes: Seq[(String, String, String)] = routesProvider.get.documentation
}


--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Michael Slinn

unread,
Oct 12, 2017, 1:27:21 PM10/12/17
to Play Framework
Here is some code that I wrote a few days ago in response to a similar question. I thought I had posted it, reposting because I don't see it on this forum for some reason:


package controllers

import javax.inject.{Inject, Provider}
import org.webjars.play.WebJarsUtil
import play.api.i18n.I18nSupport
import play.api.mvc.{MessagesAbstractController, MessagesControllerComponents}
import play.api.routing.Router
import play.twirl.api.Html
import views.html.mainBootstrap

class PathController @Inject()(
  mcc: MessagesControllerComponents,
  routesProvider: Provider[Router]
)) extends MessagesAbstractController(mcc) with I18nSupport {
  lazy val routeDocs: Seq[(String, String, String)] = routesProvider.get.documentation
  val className: String = getClass.getName

  def index = Action { implicit request =>
    val thisMethod: String = className + "." + getClass.getMethod("index").getName

    val info: String = routeDocs.map { case (method, path, controllerMethod) =>
      val marker = if (thisMethod==controllerMethod) "<b>This route serviced the request for the page you are looking at:</b>\n" else ""
      s"""${marker}method: $method
         |path: $path
         |controllerMethod: $controllerMethod
         |""".stripMargin
    }.mkString("<pre>", "\n", "</pre>")
    Ok(Html(info))
  }
}

Reply all
Reply to author
Forward
0 new messages