If you analyze a HTTP based application, every execution of logic consists of three things. First there is a HTTP method called as well as a specific URL. Optionally, the request may include a payload like request parameters or a request body. No matter what you look at: a news or a blog article, your favorite social network, you are bidding for some item during an online auction, or delete e-mails in your web mail account, you always use an URL an a HTTP method. Any unbelievably complex application such as Google Mail basically boils down to this contract. So what would be easier for a web application than to resemble this contract by mapping the tuple of HTTP method and HTTP URL to certain actions. This is what the routes file is for in Play.
As seen some time back in the filesystem layout, after creating a new application, there is a conf/routes
file. This file can be seen as the central point of your application. In order to have a truly REST based architecture, the combination of the HTTP method and URL define an implicit action. Using HTTP GET on any URL should never ever change any resource because such calls are seen as idempotent calls and should always return the same result.
In order to fully understand the importance of the routes file, this graphic illustrates that it is the starting point for every incoming HTTP request:
The image is also available at http://www.playframework.org/documentation/1.2/images/diagrams_path.
Basically the router component parses the routes file on startup and does the mapping to the Controller.
Always be aware that no logic can be executed from an external source if not triggered by the router component, which in turn is configured by default in the conf/routes
file.
Edit your routes file as shown in the following code snippet:
GET / Application.index POST /users Application.createUser GET /user/{id} Application.showUser DELETE /user/{id} Application.deleteUser # Map static resources from the /app/public folder to the /public path GET /public staticDir:public
The preceding example features a basic application for user management. It utilizes HTTP methods and URIs appropriately. For the sake of simplicity, updating a user is not intended in this example. Every URI (alternatively called a resource) maps to a Java method in a controller, which is also called an action. This method is the last part of the line, with the exception to the HTTP resource /public
, where the public directory is mapped to the public URI. You might have already noticed the usage of some sort of expression language in the URI. The ID variable can be used in the controller and will contain that part of the URI. So /user/alex
will map alex to the ID variable in the showUser
and deleteUser
methods of the controller.
Please be aware that some browsers currently only support GET and POST methods. However, you can freely use PUT and DELETE as well, because Play has a built-in workaround for this which uses POST and setting the X-HTTP-Method-Override header telling the framework to execute the code as needed. Be aware to set this request header when writing applications yourself, that connect to a play-based application.
As seen in the preceding screenshot, the router component can do more than parsing the routes file. It is possible to have more complex rules such as using regular expressions.
Using regular expressions in the URL is actually pretty simple, as you can just include them:
GET /user/{<[0-9]+>id} Application.showUser
This ensures that only numbers are a valid user ID. Requesting a resource like /user/alex
now would not work anymore, but /user/1234
instead would work. You can even create a List from the arguments in the URL with the following line of code:
GET /showUsers/{<[ -9]+>ids}/? Application.showUsers
In your application code you know you could use a List<Integer>
IDs and show several users at once, when the URL /showUsers/1234/1/2
is called. Your controller code would start like this:
public static void showUsers(@As("/") List<Integer> ids) {
This introduces some new complexity in your application logic, so always be aware if you really want to do this. One of the usecases where this is useful is when you want to use some sort of hierarchical trees in your URLs, like when displaying a mailbox with folders and arbitrary subfolders.
You can also use annotations to create routing, which offers you some more flexibility. See the first recipe in Chapter 2. Furthermore, routing can also be done for virtual host, and this will also be presented later on.
18.191.234.150