Play framework tip of the day

Sometimes Eclipse will randomly decide not to rebuild your project, insist you haven’t added something that you just added, and throw errors all over the place. You can trick it into behaving itself by closing and reopening the project. I don’t know why that works but sometimes it helps when nothing else does.

So what is the play framework anyway?

The Play framework is a super scale lightweight java (and Scala) web app framework. It’s built on top of Akka, a toolkit and runtime, which, to quote their website: helps you build highly concurrent, distributed, and resilient message-driven applications on the JVM.

So why is Play special and what makes it so different from something like Spring?

Play gets all kinds of nifty async features from Akka. Normally java is all synchronous – if you need to get something from the database or from another system, your app blocks until it gets a response. Play doesn’t block, it just picks the request back up when the response comes in (or times out), allowing it to serve other requests instead of just standing around. This means you can serve more requests without paying for more servers.


Another cool thing about Play is that it’s RESTful by default. Play’s endpoint configuration lends itself really easily to clean REST interfaces.

Here’s an quick little example of how Play endpoint config works:

# Display a client
GET    /clients/{id}     

Isn’t that pretty? It’s so clean and shiny :)

GET is the HTTP method accepted for this endpoint, surprisingly enough. /clients/{id} is the URL (relative to your project). {id} is a placeholder for the client id that gets passed in as part of the URL, and is the controller and method that handle this request. Compared to old-school Spring xml config this is freaking amazing. I even like it better than Spring 3 annotations because all my routes are clearly defined in one file. If I need to look up the exact parameters a route needs so I can test it or document it or whatever, there’s one and only one place I need to look.

Play also has an awesome php-like “just refresh” workflow. Yes, if you can get Eclipse to talk to your local app server you can make a very limited amount of changes without doing a full rebuild and redeploy, but Play does it so much better. Once in a while I have needed to do a full clean and rebuild but only if the code has changed a lot, like when I switch from a feature branch with a major refactor back to the staging branch. If you haven’t done that, then Play will load your changes as soon as you make another request.

Another thing I really like about Play is its non-maven build tools! Play uses sbt (scala build tool), which unlike maven actually works. When you add dependencies, sbt pulls them in! every time! In the entire 8ish months I’ve been working with Play, I have never (not even once!) needed to delete my entire local repo and re-download everything like I used to have to do with maven all the time. I’d honestly rather manage dependencies manually by checking them all into my repo than use maven ever again, so you may want to take the maven hate with a grain of salt, but sbt really does work well.

Play’s config file syntax is in HOCON (Human-Optimized Config Object Notation, looks a lot like JSON), which is so much easier to read and edit than xml. It takes some work to write an invalid config, and even if you manage it it’s much easier to figure out what you did wrong and how to fix it than it is with verbose xml tag names.

As for the actual code, Play hasn’t been that hard to adjust to. I’ve been using Spring and Struts for years and the basic controller/action setup isn’t that different. The async stuff like Promises is pretty weird to get used to, but if you’ve done much of any javascript then it won’t be totally new. It’s not so very different from making an AJAX call – you know what you’re supposed to get back, just not exactly when you’re going to get it.

One thing to keep in mind though is scope, particularly if you’re also using a dependency injection framework like Guice. Every time you hand off computation to another thread you lose the previous scope. Things can get ugly when you thought you had a user account id in scope but it turns out you don’t – that might sound like a stupid mistake but it’s pretty easy to do if you’re trying to put together a complicated result with data from different subsystems. Thanks to the magic of dependency injection everything will compile happily and you won’t know you lost your id until you start getting dependency injection errors all over your logs.

All in all I’m really enjoying working with the Play framework and recommend trying it out.