Writing a URL Shortener in Scala - The Good, The Bad, The Ugly

November 23, 2009 📬 Get My Weekly Newsletter

I finally got around to finishing Shorty, my url-shortener for my vanity short-domain, ❺➠.ws. I did the whole thing in Scala as a way to create a fully-functining application that I would use and that I could finish in my non-work time. Scala unequivocally made this task enjoyable and quick. J2EE, on the other hand, did not help one bit.

The Good

Scala

My Scala code is so much shorter and easier to follow than the Java equivalent. Consider this code that, given the request path, finds a controller to handle it, and then calls the appropriate method based upon the HTTP method:

route(path) match {
  case Some(controller) => {
    val result = determineMethod(request) match {
      case GET => controller.get(params(request))
      case PUT => controller.put(params(request))
      case POST => controller.post(params(request))
      case DELETE => controller.delete(params(request))
    }
It's highly readable, and very concise; the Java version would've required a lot more variables, some noisier control structures, and a lot more braces and parens.

ScalaTest

ScalaTest resulted in a lot more readable code than JUnit or TestNG would've. Because of Scala's syntax, the tests are also free of weird dots and "literate" syntax that isn't quite that literate.

it ("should respond to get for a URL that is known") {
  val controller = new OneUrlController(hasher,"738ddf")
  val result = controller.get(Map())
  result.getClass should equal (classOf[URL])
  result.asInstanceOf[URL].url should equal 
    ("http://www.google.com")
}
The delineation between "expected" and "received" could not be more clear. assertEquals just isn't the same. The latest version of ScalaTest has some BDD options that look really great.

The Bad

SBT

I really wanted to like SBT, and, while it's a billion times better than maven, it's still not as easy to use as I'd like it to be.

I like:

  • Building code and downloading dependencies are separate
  • The save/run-tests loop is very handy
  • JavaRebel + re-deploying the webapp on file save is very handy
However:
  • The test output is horrid; big huge stack traces
  • Constant OutOfMemory errors that it traps and then doesn't exit. I had to kill -9 SBT a lot
  • Still more complicated than shell scripts
I believe that a build tool should be a DSL for automating software development tasks, which means it should be more concise and easier to use than UNIX shell scripts. Ant, Maven, and SBT fail miserably at this.

While SBT is light-years ahead by using an actual programming language, I found it very difficult to customize. Part of this is that the scaladoc tool gives developers no help in documenting their API, but, when it comes down to it, Scala and Java are not system automation languages.

scaladoc

Scaladoc is nowhere near as powerful as Javadoc. It makes it very hard to document how to use your code. Scala should have a more advanced documentation system than Java, but it actually has a much more primitive one; even RDoc is better. Hopefully, as Scala's popularity increases, the tools surrounding it will improve.

The Ugly

J2EE Deployment

Deployment is an underappreciated aspect of why Rails is so easy to use; copy/push your code to the production server, tell it you are running in production, and go. With J2EE, you get NONE of this.

If you want to alter configuration based upon environment, you are entirely on your own. J2EE, Ant, Maven, and SBT give you no real help or support; you have to roll it yourself. I'm just shocked at this omission; J2EE is ten years old and still has not provided a solution for something that every project needs. Amazing.

Servlet Spec

Java 5 is at end of life. The latest released Servlet Spec still doesn't support generics and is still completely schizophrenic about it's API (some methods use Enumeration, some use arrays, some use Iterable. Ugh).

The 3.0 spec looks slightly more sane, but it really doesn't do us any favors. web.xml is a trainwreck of stupidity, there's zero support for conventions, and the whole thing just feels like a solution designed for a problem that few of us ever have.