Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Having fun with the Play! Framework

Those of you who have read this blog for a while know that I’ve spent a considerable amount of time with ASP.NET. In fact, I’ve been using ASP.NET since version 1.0, written several books that involve ASP.NET (including ASP.NET 4.0 Unleashed with Nate Dudek), and have done a ton of work with ASP.NET MVC. I’ve also written a pile of applications in Ruby on Rails. I’ve even written an application with Groovy on Grails.

To say that I am a fan of MVC-based web application frameworks would be like saying that a Bugati Veyron is a “kinda fast” car.

So when I saw Play!, a Java-based (and Scala, but we’ll cover that in another post) MVC web application framework, I figured I’d give it a shot. I have to admit that I was a bit skeptical at first. The concept of quick, fast development in a fluid, agile style doesn’t exactly scream “Java”, but I was open to having my mind changed.

The first thing I noticed was that there are no class files. The “play” interactive shell (which I believe can be run as a service for production deployments) takes care of the live compilation for you whenever anything changes. Sweet! That is about as un-java as you can expect… I fully expected to have to run some obtuse Maven build every time I changed the color of a span on a page.

The structure smells very much like an ASP.NET MVC application. There’s an app folder and beneath that you have controllers, models, and views. Each controller class is just a Java class that inherits from a base controller and is responsible for rendering a page.

There’s a routing table that works very much like ASP.NET MVC’s internal routing tables but doesn’t require me to write code to generate routes like MVC, they’re in a text file like Ruby and Grails:

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET     /                                       Application.index

# Ignore favicon requests
GET     /favicon.ico                            404

# Map static resources from the /app/public folder to the /public path
GET     /public/                                staticDir:public

# Catch all
*       /{controller}/{action}                  {controller}.{action}

There’s a great deal of flexibility in this routes file that I haven’t covered. If you’re interested, head over to the Play! website and check the documentation and tutorials which are actually pretty good.

The Play! template language looks very similar to ASP.NET MVC as well, allowing you to blend HTML elements, function calls, variables, and more all in one fairly seamless HTML file. It’s not quite as concise as the ASP.NET MVC Razor syntax, but not as ugly as the old non-Razor syntax:

#{extends 'main.html' /}
#{set title:'Hello World' /}

Greetings, ${userName}<br/>

A view like this is made possible by calling render(userName) inside a controller. Note that unlike a property bag style usage from ASP.NET, I don’t have to give the userName variable a key – the view template knows that variable name implicitly. If I passed in a complex object such as user, then I could do things like ${user.name} in my template view.

The #{extends ‘main.html’ /} tag works very much like master pages or content place holders in the ASP.NET world. Main.html has some wrapper markup and then it identifies where extensions can take place. The hello.html content will appear wherever that content extension is indicated. You can get fairly advanced and have multiple content placeholders in a template, you can chain extensions like master page inheritance.

Finally, the other thing I liked about Play! is that it uses a built-in dependency management system for the framework itself but then resorts to Maven for resolving external dependencies. So, if my application depends on some other artifact that is floating around in a public nexus, I can just add a line like this to my dependencies.yml file:

– play
org.ektorp -> org.ektorp 1.2.1

When I run play dependencies from the command line, the dependencies are resolved, downloaded, and stored in my lib directly, along with all transitive dependencies.  To be honest, if I had to manage my own dependencies for an MVC framework, I would never have even made it to “hello world”.

Overall I’m fairly impressed with Play! and will be continuing to play around with it and see what it can do and how it might be limited (or superior) to other MVC frameworks I’ve used in the past.