The Play Framework is a relatively new open source web application framework written in Java. Play follows the model-view-controller pattern and aims to optimize developer productivity by emphasizing convention over configuration, hot code reloading, and Play targets RESTful architectures. To begin let’s download the latest Play release and get started.
Creating a Project
Since we are most interested in RESTful architectures in this blog post we are going to build the familiar Dictionary RESTful Web Service using Play. The first step in creating our Play application is to run the “play new PlayDictionaryService” which will create a new Play application called PlayDictionaryService. A directory will be created that contains all of the application files. For those of you that use Eclipse as your IDE, you can run the “play eclipsify PlayDictionaryService” to generate an Eclipse project for your application.
Project Directory
The PlayDictionaryService directory will contain five subdirectories: app, test, conf, lib, and public.
app: The app directory contains the java files for the application, split into model, view, and controller packages. It can contain other packages as well.
conf: The conf directory contains the applications configuration files which include the application.conf file, the routes file, and the messages file used for internationalization.
lib: This directory contains the required .jar files for the application.
public: This directory contains all the public resources such as stylesheets, images, and html files.
test: This contains all the applications tests which can be either JUnit or Selenium tests.
Modifying the Config Files
For our RESTful Web Service to operate correctly we need to modify a few of the application config files. Since we are going to be using a database, we need to add a line to the application.conf file. For our simple database we are only going to use an in-memory database and this can be specified by adding db=mem in the config file. If we wanted to use an enterprise database such as MySQL we could change this line to be something like db=mysql:user:pwd@database_name. We also need to modify the routes file which is the file which tells Play which controller methods map to which urls.
GET /dictionary Dictionary.all
POST /dictionary Dictionary.create
GET /dictionary/{id} Dictionary.read
PUT /dictionary/{id} Dictionary.update
DELETE /dictionary/{id} Dictionary.delete
This is also pretty straightforward. A GET for the top level dictionary calls the all method and a POST to the top level dictionary calls the create method. A GET which has an id in the url calls read, and a DELETE with an id calls the delete method. And lastly a PUT request must have an id and it will call the update method.
Creating our Model
The only model that we need for our Dictionary Web Service is the Word. Creating our model class will be pretty simple since our Word object only has a name and definition. Also Play uses JPA and Hibernate as its object-relational mapping tool. What this means is that we can declare our mappings directly in the class files. Using the @Entity annotation we are telling Play that the Word class is a managed JPA entity. Also we are going to have our class extend the Model class that is part of the Play framework. This superclass automatically provides a set of JPA helpers and an @Id field that will be used as the primary key for our Words in the database.
Creating our Controller
All controllers in Play use Controller as their superclass. The controller class contains methods or actions that are invoked when a HTTP request is received. The Controller superclass contains methods that extract data from the request, reads or updates the Mode objects and sends back the HTTP wrapped response to the client. Our dictionary service has the four basic operations, Create Read Update and Delete words, so we will have four action methods in our controller. We will also add a fifth action to read all the words in the dictionary. Our five action methods are shown below.
public static void all() {
List<Word> words = Word.find("order by name").fetch();
renderJSON(words);
}
public static void create(@Valid Word)