The Play framework is a fresh, agile Java alternative to bloated enterprise stacks. It focuses on developer productivity and targets RESTful architectures. On the other hand, Scala is a hot new functional/object-oriented, JVM-based programming language. It is fully interoperable with Java, but being more concise and powerful, an interesting alternative for developers.
The Play framework’s goal is to ease web application development, but the default target language is still Java. However, an alternative called Play Scala is in development, which enables you to use the Scala language for your application while keeping key properties of the Play framework. This post sums up the evaluation of Play Scala's default features, or technology choices, and lists a few alternative technologies.
The main focus is on trying things out hands-on, especially the data access layer options.
The Maturity of Play Scala
First of all, I think it’s worth mentioning that there are people (with hands-on Play Scala experience) who feel that Play Scala is not quite as mature as Play Java. That is understandable, as Play started as a Java framework and I guess Java is still the main target. Some of the key guys behind Play, like Guillaume Bort and Sadek Drobi, seem to be fans of Scala and functional programming, so I’m expecting a bright future for Play Scala as well.
Also, while writing thism I found out that Play Scala documentation is not as extensive as Play Java documentation. That will hopefully change in the future.
Play’s Google group has some discussion about the maturity of Play Scala that might be worth reading.
Data Access Layer
One of the most notable differences between Play Scala and Play Java is the provided default data access layer. Play Java utilizes Hibernate (a JPA implementation) to provide access to a database. But with Play Scala, the use of JPA is discouraged and an alternative default data access layer, called Anorm, is provided.
Unlike Hibernate, Anorm is not an ORM. It’s built on top of JDBC and uses plain SQL to make database queries. It provides APIs for parsing and transforming the resulting dataset. That may sound like a step backwards since there are already ORMs that do the somewhat laborious work of constructing SQL queries and handling the resulting dataset. But according to authors of Anorm, when we have the power of a higher level language – such as Scala – at our disposal, there is no need to have an ORM working for us. It may actually start working against us at some point (and that’s true in the Java world as well).
Even though using JPA with Scala is discouraged, some people do it anyway. But the truth is that JPA and Scala isn’t a match made in heaven. There are problems with the way Scala annotations work (although, starting from Scala v2.8, nested annotations are supported), there is no support for Scala collections, there are differences in the reflection API (I don’t know the details) and so on. See the discussion about Play Scala and JPA.
Anorm and JPA are not the only possible data access layers for Play Scala. Some people feel that plain SQL is not the best way to go and one would benefit the most by using a data access layer that uses a (SQL-like) DSL instead. For example, ScalaQuery is an API / DSL built on top of JDBC for accessing relational databases in Scala. It’s referred to as the most mature pure Scala non-ORM database access layer. Pure Scala ORMs exist as well, such as Circumflex ORM.
There is a pretty good introduction to the different alternatives on Stack Overflow: Wanted: Good examples of Scala database persistence.
Hands-on: Data Access Layer
In order to get a better understanding of different data access layer options, I tried out a few of them in real life.
Anorm felt a bit obnoxious. I really don’t mind writing plain SQL, but knowing the benefits of a DSL, I just don’t see the point. In addition, the parser syntax is not very intuitive. Obviously, you just need to learn it, but still, the syntax looks pretty off-putting. After using Anorm, I definitely wanted to try out some of the alternatives.
ScalaQuery was a step up. Installation was a no-brainer. Adjusting to it takes a little bit more time, but I like the Scala-like approach. This shows up in, for example, the way queries are built with using the for comprehension. However, the project documentation is almost nonexistent.
The approach used in the official documentation is to deal with column projections instead of objects (definitely not an ORM). In other words, whenever something is queried from a database, the resulting dataset is not mapped to an instance of the corresponding domain model(s) but to a tuple construct with a variable amount of columns. This leaves out the abstraction of mapping results to objects. However, it is possible, with a little bit of extra work, to handle the mapping, too.
Circumflex ORM: you will need to implement a Play specific connection provider for Circumlex ORM in order to use a Play managed data source. Although this is not too big an effort, it can still be a daunting task for less experienced developers.
Compared to ScalaQuery documentation, the Circumflex ORM documentation is actually quite good.
With my background, Cirumflex ORM was the most approachable data access layer of the three that I tried out. It is also probably the easiest to get used to if you are coming from the JPA world. Note that it would be good to consider using the Criteria API to avoid performance issues when joining several relations.
All in all, Play Scala with the Circumflex ORM was a positive experience. Circumflex ORM is actually being used in the project that I’m currently working on, even though we have had some issues with it (especially with Circumflex v1 and its Oracle dialect). I still recommend it.
Play comes with a JSON library called GSON, but according to experiences that some people have had with it, it may not be the best possible JSON library to be used with Scala. It apparently has problems, at least when dealing with Scala collections.
Fortunately, an alternative JSON library called Lift JSON is available. It comes with the Lift framework, but it’s not tied to it. In other words, it can be used with Play Scala as well.
Just before posting this, I learned that in future versions of Play Scala, GSON is replaced with a library called sjson. However, at this time I have zero experience with sjson but I'm assuming that it does its job well. After all, sjson was chosen over Lift JSON (which was already mentioned on the Play Scala roadmap) to be the default JSON library for Play Scala and I'm confident that there is solid reasoning behind that decision.
Just like Play Java, Play Scala features a testing framework and templating engine. Both are different from Play Java: the testing framework is based on ScalaTest and the templating engine uses Scala instead of Groovy and has a design inpired by ASP.NET Razor.
One nice feature of Play is its pluggable modules. CRUD and secure, the modules that come with Play, seem to be especially popular. With Play Scala, however, you seem to be currently out of luck when it comes to those modules. The CRUD module, for example, is JPA dependent.
Alternatives to Play Scala
While writing this, I was left under the impression that Play Scala, being a full stack framework, is more complete and ready for development out-of-box than most of the Scala-based alternatives. That is, after installing Play, you just need to type “play install scala”, “play new [something] –with scala” and “play run” and you have a running web application.
On the other hand, Play Scala still seems a bit immature, especially when compared to Play Java. The documentation of the Scala version is not quite there yet. Plus, if you just need to write a RESTful backend that spills out JSON, you probably do not need all of Play’s features.
Based on my hands-on experiences and comments that I’ve read from the Internet, I can pretty confidently say that Play Scala is ready for (production) use as is. However, not all the nice features of Play Java work with Play Scala. For example, when doing quick demo applications, you might miss the handy CRUD and secure modules. But then again, the power of Scala itself may compensate for the missing features when considering overall productivity.
You might want to consider using alternative components/libraries in place of some of the default ones, especially as it is very easy to take them into use with the Play’s dependency management system.
The default data access layer, Anorm, seems to do its job, but I still wouldn’t use it. I don’t quite buy the arguments of using plain SQL over a DSL. I would probably choose Circumflex ORM as it seems to be the most productive without doing too much magic under the hood. As an alternative, some of the DSLs / APIs built on top of JDBC (like ScalaQuery or Squeryl) seem to work well enough.
For JSON stuff – and I’m saying this purely based on arguments I’ve read from the Internet – I wouldn’t touch GSON. When working with Scala, simply better options are available, such as Lift-JSON or sjson.
But overall, I’m giving a thumbs up for Play Scala!