Scalatra Rules

If you’re doing Scala development and want to save yourself a ton of time and headache, seriously check out Scalatra. I’ve worked quite a bit with the Play framework and worked against Spray, and I have to say that Scalatra is just a joy to use. I might name my kid Scalatra. Scalatra Legler. It rolls right off the tongue. That’s how impressed with it I am.

I’m not going to knock Play too much because it is a great piece of software. It’s just really heavy if all you need is web services though, and I’m not crazy about the functional testing framework (I’m looking at you FakeApplication, you crashy bastard). That’s beside the point though. I’m building an app that makes heavy use of web services and websockets, but the entire front end is javascript. I don’t need Play’s templating etc, so it’s just overkill. I researched micro frameworks and out of several, I decided to play around with Spray and Scalatra. Actually, I shouldn’t say that. I decided on Spray because it is so tightly integrated with Akka, which I use extensively, and so began the trouble.

The Spray toolkit is nicely decoupled, so you can use just the part you need, which I like. I love their caching module, in fact, I use it with Scalatra. I found their routing really cumbersome though, and I hate how implicit everything is. There is a lot of magic going on, which I don’t like. I’m building a REST service. If I want to send a response code with a json payload, that should be trivial. I shouldn’t have to look that up. I certainly should have to spend hours looking it up and learn an entire new vernacular of Spray idiomatic concepts to express what I am trying to do. Yet hours into messing with it, I found myself in the bowels of various google groups finding out that I have to write customer marshalers to do it? (again, we can’t agree to call them serializers? We have to come up with different terms?) Fucking annoying. The problem that put me over the edge was trying to return a 204 Status message if there were not results to display. This is a really really really common thing to do, and for the life of me, I could not get Spray to do it. This should be a one liner. I also wanted to throw 400 status codes when url parameters were missing with details as to what was missing in Json. Again, totally normal, should be a one liner, and a total fucking nightmare in Spray. I am sure that once you learn the idiosyncrasies of Spray, it’s a delight to use; however, I have shit to do and it was driving me crazy. Enter Scalatra.

At the point I went to Scalatra, I was completely disgusted with the Scala community’s acceptance of stupid complexity. This happens regularly for me. The people are great, but the idea that this complexity is acceptable is irritating. The Scala community at large needs to step back and start thinking of best practices for the language. It seems like the people with the loudest voices in the community have raging boners for the most complex abstract mathy ways to do everything. It’s exhausting. The thing about Scala is though, that if you ignore those people, the language is awesome. You don’t have to go down the pure functional hole to get performance out of it. I write Scala using the Zen of Python as my guide. It works great, and it makes me not feel guilty about ignoring the people running things. In any case, Scalatra is sweet relief from the abstract implicit horseshit going on in the Scala community. They’re my kind of people.

Let’s get back on task here and use an example to do it! For example, let’s say you have a parameter called name in your url, from which you’d like to get a value, probably a name if you’re into obviousness the way I am. Let’s say you want to throw a 400 code if it is missing and a json response explaining what happend. There are lots of ways to do this, but an easy one for me was something like this: Create a case class called HaltReason that contains a string called error. You’ll use this to deliver the message to your users of what the problem is. In your Servlet, extend ScalatraServlet with NativeJsonSupport. You do this to convert your HaltReason object into json. Then get your value with this line of code:

val name = params.getOrElse("name", halt(400, HaltReason("missing name parameter")))

Boom, that’s it. It either gets it, or it throws a useful explicitly defined error with an explicitly defined message to your user. Did I just blow your mind? If I hadn’t written that example and explanation, I’ll bet it would have pissed me off. I need examples man. I can’t conceptualize things like that. To remedy that, here is an example of the code in context.

Note: I didn’t compile this, so there may be syntax problems, but you get the gist. I also added a method that will always return a 204 response, just for awesomeness’ sake. You can imagine writing some code that results in no result, and then you can probably imagine explicity returning a response that says so. Imagining is fun.

import org.json4s.{ DefaultFormats, Formats }
import org.scalatra._
import org.scalatra.json._
case class HaltReason(error: String)
case class MyDumbResponse(name: String)
class ApiStoreServlet extends ScalatraServlet with NativeJsonSupport {
 implicit val jsonFormats: Formats = DefaultFormats
 // I put all of my routes here, this may not be totally normal. Check out the Scalatra website for real examples.
 before() { contentType = formats("json") }
 get("/getName") { doSomething(params) }
 get("/throw204") { doSomethingElse(params) }
 def doSomething(params: Params): MyDumbResponse = {
  val name = params.getOrElse("name", halt(400, HaltReason("missing name parameter")))
 def doSomethingElse(params: Params): MyDumbResponse = {
  halt(204) // This is just an example. I didn't even make it try to do something other than throw a 204 response.

Better? If not, check out and build an example project and try it out. Try to do the same thing in Spray. Actually, if you do it in Spray and get it working, send me the code. I gave up on it and I’d love to see it. My point is this: Scalatra makes it easy to do exactly what I wanted, and that is my favorite thing when it comes to software.

So what about Akka integration and all of that? What about the fact that it runs on old and busted Servlets. Don’t worry about it. The akka integration is perfect. You spin up an Actor system behind Scalatra, extend your Servlet with Future Support, and you can distribute and cluster until your heart is content. Worried about thread exhaustion because of the Servlets? Don’t worry, Scalatra works with Servlet 3.0+ containers, making that not a problem. It’s already integrated with Atmosphere, build some asychronous beast and make a billion dollars. Scalatra makes this stuff fun. I’m sure Spray is awesome too, but I just got frustrated with the complexity of it. I want my framework out of my way so I can do the things I want to do, and Spray just wanted my attention constantly. Play is great, but it’s heavy. Both Play and Scalatra are well documented and straighforward. Scalatra is just lighter, which I wanted and I like. There are others out there that I didn’t try as well, and I have no idea how well they work. Try them all if you like. I just really liked what I found with Scalatra. If your time means anything to you, I imagine you’ll find Scalatra to be a pretty valuable piece of software to use.

Published by


Geeky musician born and raised in Wyoming and currently living in Denver CO.

2 thoughts on “Scalatra Rules”

  1. Great post, mate. Detailed and informative. Experience rules above all else!

    Scalatra Legler, a truly great name. I’m thinking LOTR 4 material.:)

    Any thoughts on the forth coming reactive streams in Akka?

    FWIW, the forthcoming book: Functional Programing in Scala has some strong opinions on the topic of Actors. Just sharing.

    Thanks, Mike

  2. This was a very useful (and entertaining) read in my quest for trying to make heads or tails of the various Scala frameworks before I start messing with them! Thank you!

    I vote for “Scalatra Legler” also!! 😀

Leave a Reply

Your email address will not be published. Required fields are marked *