Everything's Beta

things I don't get to do at work :)

Quick starting Scalatra or In which I discover Scalatra and sbt

without comments

Over the weekend, I was researching various frameworks for implementing a REST API. Although I had already started the implementation using Tornado, I wanted to see what else was out there.

And am I glad I looked. I discovered Scalatra which seems to be exactly what I was looking for; a lightweight, sinatra-esque way to map URLs to actions that easily lends itself to testing. I especially like the uber-readable way the tests are written.

Who wouldn’t want to write tests like this?

// taken from http://github.com/alandipert/step
class MyScalatraServletTests extends FunSuite with ShouldMatchers with ScalatraTests {
  // `MyScalatraServlet` is your app which extends ScalatraServlet
  route(classOf[MyScalatraServlet], "/*")
 
  test("simple get") {
    get("/path/to/something") {
      status should equal (200)
      body should include ("hi!")
    }
  }
}

I cloned the repo, ran the examples and decided my search had ended.

However, while running the example was easy enough, I wasn’t sure of how to get started with an actual app. It looked especially cryptic since I haven’t ever used maven or sbt. I even considered bailing on scalatra for the well-known shores of tornadoweb. But, since I recently started working with Java at work, I decided to stick it out.

I’m glad I did because sbt is a pleasure to use, especially if you take the time to RTFM.

Anyway, here are the basic steps to help cut down the 0 to 60 time when starting scalatra :)

Pre-reqs:
Install java, I have java 1.6.
Setup sbt as per these instructions.

Good, now we are ready to start.
Create a new sbt project “HelloScalatra”

 mkdir HelloScalatra
 cd HelloScalatra
 sbt
# fill out the other inputs as you want but make sure you enter 2.8.0 as scala version.

Create a project definition for sbt and save it under project/build. Here’s a barebones one, refer to the docs if you want more info on creating sbt build configs.

// save as project/build/HelloScalatraBuild.scala
import sbt._
class HelloScalatraBuild(info: ProjectInfo) extends DefaultWebProject(info)
{
  // scalatra
  val sonatypeNexusSnapshots = "Sonatype Nexus Snapshots" at
"https://oss.sonatype.org/content/repositories/snapshots"
  val sonatypeNexusReleases = "Sonatype Nexus Releases" at
"https://oss.sonatype.org/content/repositories/releases"
  val scalatra = "org.scalatra" %% "scalatra" % "2.0.0-SNAPSHOT"
 
  // jetty
  val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.22" % "test"
  val servletApi = "org.mortbay.jetty" % "servlet-api" %
"2.5-20081211" % "provided"
}

Tell sbt to account for the new dependencies:

#from project root
sbt update

We have the basic dependencies taken care of, so let’s create our class that will serve requests. Create “HelloScalatra.scala” under src/main/scala/com/helloscalatra with the following content:

// save as src/main/scala/com/helloscalatra/HelloScalatra.scala
package com.helloscalatra
 
import org.scalatra._
 
class HelloScalatra extends ScalatraServlet with UrlSupport {
 
 before {
   contentType = "text/html"
 }
 
 get("/") {
   <html>
     <head>
       <title> My first scalatra webapp</title>
     </head>
     <body>
       <h1> Hello Scalatra </h1>
     </body>
   </html>
 }
 
 protected def contextPath = request.getContextPath
}

The last thing we need to do is setup web.xml to tell jetty what to do:

// save as src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
 "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
 
 <servlet>
   <servlet-name>HelloScalatra</servlet-name>
   <servlet-class>com.helloscalatra.HelloScalatra</servlet-class>
 </servlet>
 
 <servlet-mapping>
   <servlet-name>HelloScalatra</servlet-name>
   <url-pattern>/*</url-pattern>
 </servlet-mapping>
</web-app>

Great! We should be good to go :)
Go to project root and startup the sbt console:

sbt

and start jetty:

>jetty-run

TADA!

Navigate over to localhost:8080 to see the webapp in action.

Written by srijak

July 18th, 2010 at 4:43 pm

Posted in code

Tagged with

Leave a Reply