Wednesday, January 4, 2012

Experiences with The Play Framework

A friend of mine recommended I look at the Play framework.  It was about the same time as I had decided that using a stateful architecture like JSF/JEE was a bad fit for mobile development.  Play is a stateless architecture based on JPA and a page templating language that allows Groovy closures and Expression Language to bind to backend beans.  More control over the HTML output can be achieved when you are writing the markup as HTML to begin with, versus the JSF tags.  So I've spent a few weeks working/playing with Play, JQuery and JQuery Mobile and here are a few topics and lessons learned.


  1. Test Driven Development.  Play comes with a transactional test framework out of the box.  They recognize that you must test first.  Setting up a new Play project will give you a unit test (JUnit based), integration test (HTML Unit based) and a functional test (Selenium based).  You can extend and modify them to get your own testing off and rolling.  The cobertura plugin gives you code coverage right out of the shoot also, so you can see how well you are doing with your tests.
  2. JPA Extensions.  A few convenience classes extend JPA to make base entities easier to setup, and collection maintenance slightly less problematic.  The injection of entity manager into the JPA beans makes the self-reliant, i.e customer.save() will save a customer object, no need for a 3rd party manager to do the work for you.  It is critical to get this layer started off on the right foot so that you will have a nice reusable, extensible set of logic and persistence at your disposal thruout the project.  
  3. Controllers and page mapping.  The routing file maps incoming requests to controllers.  Controllers automatically marshal java POJOs and can validate them against javax.validation validators.   Error messages are re-rendered back to the ui and can be global (for the page) or field specific.  Mappings can be done based on request type, i.e. GET/POST/PUT/DELETE can map differently.
  4. Page markup is done by writing the appropriate view html file.  A controller method Widget.index will look for the view file widget/index.html.  Further the index method will use render(...args) to initiate the rendering and pass POJOs to the page scope.  Write up the index.html by extending a site wide template.  Then use the beans set in the page scope to bind the page to your beans.  For example, if a Customer class has a lastName attribute, the the input text field with the id/name of customer.lastName will bind to the bean when you save the form.  There's lots of good examples on the Play framework site and in the apps in the distribution.
  5. JQuery.  The few JQuery plugins that I've found invaluable are DataTables, MaskedInput, TimePicker, SelectMenu and RoundAbout.  These provide my application the sortable/paginated/filterable datatables, input masks for phone numbers/dates/etc., date and time picker, select one and select many pulldowns, and a carousel for scrolling thru data.  I have found that I like to define extra attributes on the html elements that I can use in JQuery selectors to control how elements get formatted.  For instance, if I change the type of an input field to be phone, then I can select and mask all phone numbers by using '$("input[type='phone']").mask("(999) 999-9999")'. 
  6. JQuery Mobile.  There's two approaches to developing pages for JQuery Mobile.  In the first method, the server will deliver an html page that has all the html your mobile site will need.  Pages are divs or articles with the data-role=page.  Hrefs can be used for this 'internal' navigation via hashtag, e.g. <a href="#pagetwo" ...  You can attach javascript to the pageinit method and call the appropriate server url to get page contents and load them dynmically.  The other option is to use 'external' page navigation where the navigation link would use an external url, e.g. <a href="pagetwo.html" ...  JQM will automatically display a loading indicator, call the server to get the page, display error message in case of problems and replace the viewable DOM.  Pretty easy but less like to work in offline mode.  I am still discovering the best options for me in this area and JQM has a good page on navigation techniques at  http://jquerymobile.com/test/docs/pages/page-links.html.
  7. Cloud Deployment.  I've used Heroku for cloud deployment for the Play applications I've developed.  Heroku has native support for Play! build lifecycle, so you are essentially performing a 'git push' and let Heroku build and deploy the application.  Postgres is the default database and the application.conf file has the settings you need to deploy to postgres.  Heroku will define a ${DATABASE_URL} that you can use in the conf file to connect to the database when in production mode:
    1.  %prod.db=${DATABASE_URL}
    2. %prod.jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
    3. %prod.jpa.ddl=update
  8. Amazon S3.  Heroku only gives you temporary file based storage so if you want to store images on the file system you need to goto a provider.  Heroku is using Amazon EC under the covers and there are a few plugins for Anazon S3 (super simple storage).  I used some java code posted by James Ward ( https://github.com/jamesward/plays3upload) and tweaked it ever so slightly to cache the images in Heroku temporary storage once they are downloaded from AS3 so as to avoid going to get them thousands of times at which point Amazon will begin to bill you.
  9. HTML Application Cache:  In concept it's like browser cache that survives restarts.  For mobile applications it can really make a difference to have javascripts, css and images already on the device. The downside of course is how to update things when they change.  Also problematic is the 'master' page will be stored in application cache too, so if the page is dynamically generated on the server things are apt to go awry.  Still working thru some issues on this one myself, but so far the pages are usable in 'airplane' mode when I use internal JQM navigation and I get less caching issues when I use 'external' navigation.
In summary, I've found working with Play! to be straightforward.  It's nice to have a web application framework that has everything you need to develop a web application right out of the box.  I am still uncertain about reuse of page markup particularly if you have a page that will dynamically update small fragments of itself.  I have written the page and the page fragment separately and duplicated markup in both. Also, the mobile pages are really similar to the browser/desktop pages with some reformatting.  Once again the display markup is duplicated.  There's not much in the markup, but it does slow things down when you need to make the same change in more than one place.

You can download Play! and learn more about it at http://www.playframework.org/.
See my application on Heroku at http://golfplus.herokuapp.com/