Question

I'm wandering if there is a way to do a regex inside the routes file, where the path may contain alphanumerics, but only the number is passed to the controller. So for example: http://example.com/person/Jay-Z-12344 would resolve properly.

GET     /person/$id<[\d]+>               controllers.App.person(id:Long)

Thanks for your help!

Was it helpful?

Solution

You'll just need to override Global.onRouteRequest to modify the URL before passing the request through to the routes, or call the controller directly.

To the controller directly:

object PersonIdRouteExtractor {
  private[this] val Pattern = """/person/[^0-9]*([\d]*)""".r

  def unapply(req: Request): Option[Long] = {
    req.path match {
      case Pattern(path) ⇒ Try(path.toLong).toOption
      case _             ⇒ None
    }
  }
}

override def onRouteRequest(req: RequestHeader): Option[Handler] = {
  (req.method, req.path) match {
    case ("GET", PersonIdRouteExtractor(id)) ⇒ Some(controllers.App.person(id))
    case _                                   ⇒ super.onRouteRequest(req)
  }
}

Modifying the request path with default routes:

object PersonRouteTransformer {
  private[this] val Pattern = """/person/[^0-9]*([\d]*)""".r

  def unapply(req: Request): Option[String] = {
    req.path match {
      case Pattern(id) ⇒ Some(s"/person/$id")
      case _           ⇒ None
    }
  }
}

override def onRouteRequest(req: RequestHeader): Option[Handler] = {
  (req.method, req.path) match {
    case ("GET", PersonRouteTransformer(xpath)) ⇒ super.onRouteRequest(req.copy(path = xpath) // not sure if you need to do the uri too?
    case _                                      ⇒ super.onRouteRequest(req)
  }
}

This could be cleaner and refactored for better reusability but you get the idea. Also check out James Roper's blog post about Advanced routing in Play Framework

OTHER TIPS

You can use Regex inside the routes but I think it is only for matching. You cannot replace the dynamic part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top