Saturday 23 June 2012

Scala and REST

I've been looking into Scala and REST recently, because I really like the idea of Scala - though to date I've not actually got on all that well with it in practice - and I really like the idea of writing webapps using the REST principles and Javascript in the client to pull it all together.

As such, I've been looking at the various frameworks that exist for writing webapps, and in particular ones that have REST support for Scala. And have come to the conclusion that the answer isn't that great. I must confess that I am rather spoilt here in that I've done a lot of work with Java frameworks (Mainly Spring) that do provide all the things I'm looking for, and I think the Scala landscape is just too new to have full featured support yet.

Frameworks

The frameworks I've looked at, and my thoughts of them are:

Play 2.0

Seems rather nice on the outside, and there's an awful lot of good press about it. However, it's one of those frameworks that seems lacking on certain features that would just make it. It isn't possible to build a WAR file to run in a standard container using Play 2.0 (Apparently that was possible in 1.0, so for some reason that's been taken out of the newer version!). It also doesn't have fantastic support for JSON marshalling. It has built in support, but only if you specify the actual mappings yourself. What I'd really prefer is to be able to just give it a class (Even better, a case class) and have it get on with it. To be fair, when you are writing JSON objects this is rather trivial, using the Json.generate method, but when you are consuming JSON this seems to be very difficult. I managed to actually achieve it, but not in a fantastic way...

Lift

Seems to be a much more fully features framework than Play, with lots of support for other nice things - the documents mention JTA and JSR 303 Validation for example. Lift also supports being packaged into a standard WAR file, and is I think the only one that I've looked at that does support this! It falls down on JSON support again though, in that it will natively consume and produce JSON using the underlying raw JSON objects - the same as Play - and it can be made to produce JSON from your own objects but doesn't seem to have any easy way to consume JSON into your own objects.

Spray

Spray I need to play with some more. I thought it was lacking in a few areas but I've just come across hints in the documentation that those areas actually are supported. Specifically all the examples I had seen imply that you need to run your own web server in the spray code, but the documents just mentioned that you can run it in a Servlet container, and tell you to go and look at the examples for how to do that.

It does still look like it expects you to do a fair bit that you shouldn't have to - one of the examples has you wrapping your controller in a handler to automatically handle GZip encoded data! Something that shouldn't need to be handled by the controllers at all, but instead by the underlying web server.

The documentation claims that it has proper JSON support too - allowing marshalling from any type and unmarshalling to any type, instead of getting raw JSON objects back that you need to work with yourself. Unfortunately the wiki pages telling you how to do those aren't written yet, so that will mean more example diving.

Blue Eyes

Blue Eyes is an intriguing one, in that it is designed to only do RESTful web services and nothing else, and has a lot of support for various things like versioning of services, path handling, and apparently JSON support (Though this is totally undocumented it seems). It even seems to have built in support for MongoDB - though why a web framework needs built in support for a data store is beyond me. It does however require you to write your own web server first, and even goes so far as to give you lots of tools to do that - including the ability to do request logging and health monitoring of your services. All things that if I ran it in my own container I wouldn't have to do!

Pinky

Pinky does support Servlet containers, but in a bizarre way. You don't write Servlets, or anything that gets called by a Servlet. Instead you write code that all gets called by the Google Guice webapp filter. It does however let you write what it calls Controllers and Servlets (seemingly interchangeably). It also claims to have out of the box support for numerous different data formats, including JSON, but is very low on documentation for those. The actual examples just feel a bit weird too - like a mash up between Java and Scala. (This is the first time I've come across pure Scala code that uses annotations, but I suspect that's because it's built on top of Guice)

Others

I'm well aware there are plenty of other frameworks to choose from - the ones I've seen mentioned include Bowler, Xitrum, Unfiltered, Finangle, Scalatra, and Play Mini, but there are loads more too that I can't name off the top of my head. However, I'm only human and looking through all of these frameworks for the One that fits what I want takes a very long time. I may get to look at some of the others in the future, and write up my thoughts on them, but to date I've had too brief a look to say anything meaningful.

Summary

When I started writing this, my conclusion was going to be that I'm going to go back to Spring MVC but writing all my code in Scala. That means the slightly weird situation of having a mixture of Java and Scala in the controllers themselves - like I just described for Pinky - but hopefully allows me to play with pure Scala code below that, and it also gives me the full power of the Spring framework to leverage, including automatic marshalling/unmarshalling of data that so many of the above frameworks lack on, and running inside a standard Servlet container.

However, my actual conclusion is a bit less solid. I think I need to look closer at Spray and Lift before I outright drop them, and maybe even Play though I have spent a fair bit of time with that and not gotten very far...


No comments:

Post a Comment