Tag Archives: scala

The Play! Framework

20 Sep

Overview

Play 2.0 is a lightweight Java and Scala web framework aimed at keeping setup and configuration time to a minimum, thereby maximising development time. Some of the key advantages that Play boasts over other frameworks is code hot-reloading, stateless and RESTful design, less configuration and asynchronous I/O.

Play 2.0 has a large focus on type safety with the idea of getting the compiler to find code errors rather than stumbling upon them at runtime. When compile or runtime errors are encountered, Play 2.0 does its best to give useful information in the error messages, which are displayed neatly in the browser.

The framework uses a Scala based template engine for the generation of web pages, but gives the programmer the choice of using either Scala or Java for server side code. Play uses the JBoss Netty web server (which comes packaged with the framework) allowing Play to service long requests asynchronously. The configuration file is small and neat, and the developer can specify a separate production config file when deploying the application.

Example config file

application.name=MyTestApplication

# Secret key
# The secret key is used to secure cryptographics functions.
application.secret="abcdeHUL__[Gf2HUfYMR/au1234`KW^T2owIxWXEoy8g:1234Kivx>3bu0X5]bq"

# The application languages
application.langs="en"

# Database configuration
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
#
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=
#
# You can expose this datasource via JNDI if needed (Useful for JPA)
# db.default.jndiName=DefaultDS

# Evolutions
# You can disable evolutions if needed
# evolutionplugin=disabled

# Ebean configuration
# You can declare as many Ebean servers as you want.
# By convention, the default server is named `default`
ebean.default="models.*"

# Logger
# You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory .

# Root logger:
logger.root=ERROR

# Logger used by the framework:
logger.play=INFO

# Logger provided to your application:
logger.application=DEBUG

The Play Console

Creating a new project with Play 2.0 is a simple process. Once you have downloaded the framework (which is OS independent) enter the following in a new command window:

$ play new myProjectName

Once the framework has created your project (you can choose at this point to either create a Java or Scala project) you can enter the console of your application by entering the directory of your newly created project and typing:

$ play

From here you have various commands available to you:

run will begin your application in the built in webserver on http://localhost:9000/. A default home page with help and links to documentation is provided.

test will run all the unit, integration and functional tests under the test/ directory of your project. The framework also provides clean, compile, debug and console commands. The console command launches an interactive Scala console that allows you to test and evaluate snippets of code.

Play 2.0 also provides triggered execution commands. ~ run will run your application and detect any changes to code files, recompile them and inject the newly compiled code into the running instance. The ~ test command will rerun all your application’s tests each time the source is modified.

The Play console also provides commands for creating project files for IntelliJ Idea, Netbeans and Eclipse, making the process of getting to actual development even faster.

Features

Play 2.0 comes with a collection of libraries, helper classes and base classes, all designed to help you avoid unnecessary boiler plate code. While using these API’s and helper classes is encouraged, you are not restricted to using them. Some of the libraries included in Play 2.0 are Ebean, FluentLenium as well as a built in SMTP mailer and job scheduler. A base Model object built around Ebean is included with helper methods for all your basic persistence requirements.

package models;

import java.util.*;
import javax.persistence.*;

import play.db.ebean.*;
import play.data.format.*;
import play.data.validation.*;

@Entity 
public class User extends Model {

  @Id
  @Constraints.Min(10)
  public Long id;

  @Constraints.Required
  public String name;

  public boolean isAdmin;

  @Formats.DateTime(pattern="dd/MM/yyyy")
  public Date birthday = new Date();

  public static Finder<Long,User> find = new Finder<Long,User>(
    Long.class, User.class
  ); 

}

// Find all users
List users = User.find.all();

// Find a user by ID
User anyUser = User.find.byId(34L);

// Delete a user by ID
User.find.ref(34L).delete();

// More complex user query
List users = find.where()
    .like("name", "%coco%")
    .orderBy("birthday asc")
    .findPagingList(25)
    .getPage(1);

Play will automatically generate any getter and setter methods on models (if they do not exist already) to ensure compatibility with any libraries that expect them to be available at runtime.

Following Play’s suggested architecture is quick and easy, but deviating from it will lead to writing some of your own boilerplate code. Many of the helper classes are coupled to specific frameworks (such as the EBean base Model object) however swapping out the persistence layer is not too difficult to do. Play also provides you with a built in JPA helper.

public static User findById(Long id) {
  return JPA.em().find(User.class, id);
}

Testing and TDD

Play 2.0 purposely lends itself quite well to test driven development. With built in JUnit and FluentLenium, as well as helpers to create in memory databases that can be used for the duration of the test session, it is easy to write tests that run quickly and that are not dependent on your production database. Nothing extra is required to write and run your JUnit unit tests, and by using the test-only command you can exclude your functional and integration tests to keep the testing in your TDD cycles fast.

$ test-only my.namespace.unittests

The continuous testing option provided by sbt automatically re-runs your tests when it detects any code changes, which is handy for picking up regression bugs early. Using Selenium WebDriver and HtmlUnit allows you to run your functional tests headlessly so that you are not distracted by the browser popping up every time your tests are run.

One downside of using Play’s inbuilt testing framework is that test results are displayed in the terminal window instead of in your IDE. This means that you will constantly be having swich to your terminal to see what tests may have failed. While the framework gives full descriptions of the failed tests, you won’t be able to make use of various IDE features such as links that take you directly to the source of the failed test.

Conclusion

The suitability of Play 2.0 for large enterprise applications has been debated quite a lot in various circles. Many people are sceptical of using it due to it being relatively new, and its tendency to not strictly follow Java EE best practices. However there are a number of high profile websites built using Play (including http://typesafe.com/), and many good testimonials littered around the internet. Play definitely seems to keep the developer in mind and provides enough extensibility and modularisation to allow the framework to fit just about any application.

Since Play’s inception in 2009, there have been some major improvements and changes and Play has continuously remained on the cutting edge. Play 1.0 is still being maintained, however the versions are not backwards compatible. Play is not a silver bullet to all your application requirements, but is certainly a framework to keep an eye on, and in the meantime it is definitely a fun framework to work with.

References

http://blog.davejafari.com/experiences-developing-with-play?c=1

http://stackoverflow.com/questions/7866186/play-framework-suitability-for-websites-and-web-apps

https://groups.google.com/forum/?fromgroups=#!topic/play-framework/zXYniwmH9KQ

http://www.playframework.org/documentation/2.0.3/Philosophy

http://en.wikipedia.org/wiki/Play_Framework#Usage

http://www.lunatech-research.com/archives/2010/03/15/play-framework-usability