Play Framework makes it easy to build web applications with Java & Scala.
Play is based on a lightweight, stateless, web-friendly architecture.
Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.
Play was the first framework I picked up in preparation for a talk Kingsley and I gave at Scala Exchange 2016; Scala Services in Action. As it is one I have used before at a previous company, I was keen to go back and see if I still enjoyed using it a year or so later. I was left with a great first impression from using it in industry, which thankfully has held true throughout my experience at home. As part of the talk preparation, I wrote a small REST application that can be found here, where all of the below examples can be found.
Play’s website was very nice to use, clear to navigate around and included plenty of sample projects to look at. This is all so very useful when looking at a framework for the first time and can’t be underestimated. Everything I needed when writing my example project was easy to find in the Scala documentation and it covered everything in a way that I understood (not as common as you’d think!).
I really liked Play routes. It felt like a natural separation to keep the routes in a configuration file away from the rest of the Scala code. You simply define the route and direct it to a method in the controller, no fussing with syntax or boilerplate. Once you start to accept payloads or query parameters there is a small amount of googling to find out the exact syntax and how to pass them into your method, but nothing too scary or time-consuming.
Play comes pre-packaged with a dependency injection framework by Google called Guice. I can’t say I’m a fan of Guice, I particularly found it to be a huge barrier when using Play as a beginner. It’s quite “magic” in the way that it does a lot of things you can’t see and, everyone knows, when magic goes wrong it’s even harder to understand and fix.
Also, as Scala developers we have come to depend on the compiler, and in most cases if it compiles, we already have a decent amount of faith it will work. Guice introduces these runtime errors into your code which is a HUGE downfall. These errors are often misleading or confusing when the project becomes more complex.
Furthermore, Guice seems to make testing quite difficult to get going with. Granted, I didn’t spend that much time battling with it, I’d already lost my temper with Guice a long time ago so my patience was wearing thin. I just found the effort in understanding what I had to do and what was going on completely unnecessary. Even though I would use Play in the future, I would not use it with Guice.
+ User Interface
Play comes with a user interface without any extra effort required. At first it may not seem like a big deal, especially if you are planning to return json objects. However, the UI helped me quite a bit when I was testing endpoints or getting runtime errors cough *Guice* cough. As shown below, if you get the endpoint wrong, it shows you all the endpoints that are available to you (thumbs up from a lazy developer).
+ Json formatters
On Play’s website it claims they aim to make Json a first class citizen. So, the good news is Play was the only framework where I successfully manipulated the json I was sending or receiving in one sitting. I was able to negate the need for certain unnecessary fields in the json to maximise usability. For example, I nested my case classes, even for those values that only needed one field like this:
This meant by using the default Play json formatters, I would need to be writing json with extra “value” fields like below. sad face.
Another example would be that you would ideally want to model your data with one case class, for example a pet:
This means this case class will model what your json will look like in the request and the response. However, it may be misleading or confusing to ask for an ID (also shown in the above json) when someone is ‘registering’ a pet, yet our service needs to respond with an ID when the user ‘GETs’ a Pet so they can use it later to update or delete.
Thankfully, Play json custom formatters (and Options) gives you a huge amount of flexibility.
– Compilation: When and How long
Play, by default, has “just in time” compilation. I realise this doesn’t sound like a huge problem, and I would agree, but it did get a bit annoying when doing what should be very quick manual tests on the endpoints. Not only do you have to send the request and wait, you have a to wait quite a while – Play does seem to be very slow 🙁 This also means that you don’t get your compilation errors until after you’ve sent a request for the first time:
which is almost as bad as runtime.
+ Cycle time
I realise that speed and usability are factors that are largely subjective and are not a clear reflection of the framework alone. However, I can claim that compared to the other frameworks I’ve had a ‘first look’ at, this tops my list in this category. The documentation is extensive and clear to navigate around, there are many templates available and every question I asked Google was answered dozens of times.
As for going from zero to service; along with the routes I have shown above, all you need is to add this to your build.sbt:
That’s it. No nasty boilerplate and nothing that isn’t directly focused on the service you want to build.
Play came out top favourite in a poll we ran during our talk in the Scala Exchange! I think this is mostly down to the excellent support and documentation you get if you choose Play, you never feel like you’re the only one who’s approached a particular problem. I saw the biggest downfall was the way it introduces runtime errors to a language that loves to depend on the compiler – I would definitely get rid of Guice.
- I found a book by Underscore incredibly useful that can be found here. Great for beginners!
- Activator is an excellent tool for developers to get started with SO MANY tutorials.
- This blog by Krzystof Pado is great at looking at all of the dependency injection techniques you can use with Play – excellent read if you are looking for an alternative to Guice.