Routing, as we saw, is the mapping of HTTP requests to Scala handlers. Routes are stored in conf/routes
. A route is defined by an HTTP verb, followed by the end-point, followed by a Scala function:
// verb // end-point // Scala handler GET / controllers.Application.index
We learnt to add new routes by just adding lines to the routes
file. We are not limited to static routes, however. The Play framework lets us include wild cards in routes. The value of the wild card can be passed as an argument to the controller. To see how this works, let's create a controller that takes the name of a person as argument. In the Application
object in app.controllers
, add:
// app/controllers/Application.scala class Application extends Controller { ... def hello(name:String) = Action { Ok(s"hello, $name") } }
We can now define a route handled by this controller:
// conf/routes GET /hello/:name controllers.Application.hello(name)
If you now point your browser to 127.0.0.1:9000/hello/Jim
, you will see hello, Jim appear on the screen.
Any string between :
and the following /
is treated as a wild card: it will match any combination of characters. The value of the wild card can be passed to the controller. Note that the wild card can appear anywhere in the URL, and there can be more than one wild card. The following are all valid route definitions, for instance:
GET /hello/person-:name controllers.Application.hello(name) // ... matches /hello/person-Jim GET /hello/:name/picture controllers.Application.pictureFor(name) // ... matches /hello/Jim/picture GET /hello/:first/:last controllers.Application.hello(first, last) // ... matches /hello/john/doe
There are many other options for selecting routes and passing arguments to the controller. Consult the documentation for the Play framework for a full discussion on the routing possibilities: https://www.playframework.com/documentation/2.4.x/ScalaRouting.
URL design
It is generally considered best practice to leave the URL as simple as possible. The URL should reflect the hierarchical structure of the information of the website, rather than the underlying implementation. GitHub is a very good example of this: its URLs make intuitive sense. For instance, the URL for the repository for this book is:
https://github.com/pbugnion/s4ds
To access the issues page for that repository, add /issues
to the route. To access the first issue, add /1
to that route. These are called semantic URLs (https://en.wikipedia.org/wiki/Semantic_URL).