Reverse Routing
Each Route
also contains enough information to generate its own URL given the necessary parameters. This lets you
build type-safe and reliable references to your application's URLs without any hardcoding. Assuming you have a route:
import routing._
val BlogPost = Method.GET / "post" / pathVar[String]("slug") :? queryParam[Int]("id")
// BlogPost: Route[GET, Tuple2[String, Int]] = /post/<slug: String>?<id: Int>
Then you can apply the necessary parameters in a number of ways to get various parts of the URL:
BlogPost.path("test-slug", 1)
// res0: String = "/post/test-slug"
BlogPost.query("test-slug", 1)
// res1: Vector[Tuple2[String, Option[String]]] = Vector(
// ("id", Some(value = "1"))
// )
BlogPost.uri("test-slug", 1)
// res2: ReverseUri = ReverseUri(
// method = GET,
// path = "/post/test-slug",
// query = Vector(("id", Some(value = "1")))
// )
// Alias of `uri`
BlogPost.url("test-slug", 1)
// res3: ReverseUri = ReverseUri(
// method = GET,
// path = "/post/test-slug",
// query = Vector(("id", Some(value = "1")))
// )
To avoid having to pass the parameters to each of these methods, you can eagerly apply the parameters to convert a
Route
to a Call
:
val blogPost = BlogPost("test-slug", 1)
// blogPost: Call = /post/test-slug?id=1
blogPost.path
// res4: String = "/post/test-slug"
blogPost.query
// res5: Vector[Tuple2[String, Option[String]]] = Vector(
// ("id", Some(value = "1"))
// )
blogPost.uri
// res6: ReverseUri = ReverseUri(
// method = GET,
// path = "/post/test-slug",
// query = Vector(("id", Some(value = "1")))
// )
blogPost.url
// res7: ReverseUri = ReverseUri(
// method = GET,
// path = "/post/test-slug",
// query = Vector(("id", Some(value = "1")))
// )