Quick starting Scalatra or In which I discover Scalatra and sbt

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.

Tagged

6 thoughts on “Quick starting Scalatra or In which I discover Scalatra and sbt

  1. atomi says:

    This was real helpful.

    I found though, that I had to run the “reload” command before running the “update” command.

    BTW, I’m glad I found scalatra too.

  2. joyce says:

    Do you know how I can package the code into a war file using sbt to be deployed into another jetty container rather than the one that comes with the framework?

    Thank you!
    Joyce

  3. Thanks for writing this up… it was just what I needed get me started!

  4. Olli says:

    Take also a look at http://bowlerframework.org/ if you’re interested in REST framework based on scalatra.

  5. Kevin says:

    @Joyce

    run the command :

    sbt package

    Then navigate to your /target/scala…/…war file

    Drop this file into your /webapps/ directory of your jetty install

    Good to go!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">