Akka and Scalatra

On my current project, I’ve been using Akka to handle the Service Layer of my application while using Scalatra for my REST controllers.  This combination works quite well, though it took me a little bit of time to figure out how to integrate Scalatra and Akka.  The examples presented on the Scalatra website didn’t exactly work for me (it’s possible they’ve since been fixed).  But after some studying of the Akka and Scalatra API documentation and some good ol’ fashion trial-and-error, I got to something that worked.  First, Akka actors are set up and initialized in ScalatraBootstrap.scala thusly:

class ScalatraBootstrap extends LifeCycle with DatabaseInit {
  //initialize the Actor System
  val system = ActorSystem(actorSystemName)
  //initialize Service Actors
  val userServiceActor = system.actorOf(Props[UserServiceActor].withRouter(
    SmallestMailboxRouter(nrOfInstances = 10)), "userRouter")

  override def init(context: ServletContext) {

    //mount REST controllers
    context.mount(new UsersController(system, userServiceActor), usersPath)


  override def destroy(context: ServletContext) {
    system.shutdown() // shut down the actor system

I’m initializing each actor with a router (in this case, a SmallestMailboxRouter, though others, such as a RoundRobinRouter are also available).  The router will create up to 10 child actors and route incoming messages to the actor with the least number of ‘messages’ in its inbox.

The Scalatra controller responds to a request for a resource by sending a message to the appropriate actor (I’m using one Actor type per resource) using a Future and returning the result.  Scalatra provides an AsyncResult construct that helps here:

  /** Get a specific user's information
    * User-id specified by id
  get("/:id", operation(getUser)){
    basicAuthWithCustomerCheck() match {
      case None => //do nothing
      case Some(user) =>
        new AsyncResult{
          val is: Future[_] =
            ask(userServiceActor, new GetUserByIdMessage(user,
              mapTo[Either[(Int, String), UserDto]] map {
              case Right(userDto) => userDto
              case Left((errorCode, msg)) => response.sendError(errorCode, msg)

My actor here happens to return an ‘Either’ type in response to a request.  By convention, a ‘Left’ response indicates an error condition (in this case a tuple containing the HTTP error code to return and a message), and a ‘Right’ response indicates success and contains the requested data (a ‘User’ object). The actor itself looks like this:

case class GetUserByIdMessage(user: User, id: Long)

class UserServiceActor extends Actor{

  def receive = {
    case getUserByIdMessage: GetUserByIdMessage =>
      sender ! handleGetUserByIdMessage(getUserByIdMessage)

  def handleGetUserByIdMessage(getUserByIdMessage: GetUserByIdMessage):
  Either[(Int, String), UserDto] = {
    //Process request.  Return an (error code, message) tuple on failure, and the
    //data on success  

The message types are implemented as case classes, and enter the actor in the ‘receive’ method, which passes each message to a handler and returns the result to the message’s ‘sender’ (the controller).