user2657794
user2657794

Reputation: 278

Play 2.1 Scala Routing

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!

Upvotes: 0

Views: 117

Answers (2)

tysonjh
tysonjh

Reputation: 1339

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

Upvotes: 1

James
James

Reputation: 1446

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

Upvotes: 1

Related Questions