I recently started working on a new project and decided to go with Scala and the Lift framework for the backend.

I like Lift a lot, having build a previous website entirely using it. Since then, it became my “go to” standard for whenever I had to build something web-related.

For this project, we had to build a mobile application and a backend server to share the data between the (hopefully) many clients. I was not too familiar with the best way to have mobile applications communicate with a server, but I decided to just jump in and chose the simplest solution that I knew: implementing an HTTP-based server and have the clients communicate with it using an HTTP library.

I wanted to experiment with something new for the hosting. I used to work with dedicated machines or VPS, but that was a bit of a pain to maintain. I had heard a lot of good things about Heroku, so I decided to give it a try.

The great thing with Heroku is that, once setup, deploying is as simple as doing a git push. However, all this simplicity comes to the price of flexibility. If you want to use Heroku, you have to build your application in a very specific way — the Heroku way. In particular, you can no longer organize your architecture around full computer boxes, but need to think of your application as a collection of different processes, independent of the rest of the system.

That means two things. One, you can no longer rely on the local filesystem or memory being in an expected state accross several requests, and two, you will need to connect with several external services for tasks such as persistence.

Essentially, Heroku forces you to build stateless applications. That is, applications that handle requests in a stateless manner, with no dependency on any previously completed requests. Concretely, that means we will not have a login request that sets session data on the server and remembers which user correctly logged in, but instead, each request that needs authentication will contain some sort of credentials to identify and authorize the client.

Building a stateless application is very good when you need to scale horizontally. Since a server treats each request in a stateless way, it is straightforward to fire up additional copies of the same server and have a load-balancer dispatches the request to the least busy server. In fact, that is exactly what Heroku is doing, only that the dispatching is done randomly, which on average is pretty much the same. In theory, if you implement your backend properly with Heroku, you can scale up by just flipping a switch in the Heroku console.

But Lift is relying on state. Sessions are combined with closures to handle ajax callbacks in a very convenient and efficient way. This is a powerful feature, but it means that a Lift server is not stateless, as the follow-up ajax requests will need to be handle by the same server that created the closures in the first place. There is a known solution around this problem: sticky sessions. Sticky sessions are a configuration mode for load-balancer that simply make sure that all requests in the same session are always routed to the same server. That does not solve the issue of a server restart during a session, but in most cases this is a perfectly fine solution.

Unfortunately, Heroku does not support sticky sessions. You have no control over the Heroku load-balancer, it simply routes each request independently and randomly to an instance of your application. Does it mean we cannot use Lift when hosting on Heroku? No, but it means we have to avoid the stateful features of Lift.

In our case, we wanted to use Lift to build an HTTP API for a mobile client. Lift provides a RestHelper helper trait which facilitates the creation of web services. We start by defining some API endpoints, let’s take a user system API for example:

class UserAPI extends RestHelper {
  serve("api" / "users" prefix {
    case AsLong(id) :: Nil Get _ => ???
    case AsLong(id) :: Nil JsonPut json => ???
  })
}

This defines two URLs for our API. The first one accepts a GET request and is supposed to return a resource representing the user represented by its id. The second one is meant to update the user based on a json resource object received as part of the request. The implementation of these endpoints are relatively simple but dependent on your system. Essentially, it is a couple simple database queries to get and update the data of the user. It is essential that those do not rely on session data provided by Lift (most of the S object).

Next, we can setup Boot.scala in the following way:

LiftRules.enableContainerSessions = false
LiftRules.statelessReqTest.append { case _ => true }

LiftRules.statelessDispatch.append(new UserAPI)

This forces Lift to operate in stateless mode. It will even throw an exception if you have some code relying on session data. In the final statement, we append the UserAPI instance to the statelessDispatch list that Lift goes through before initializing session state when receiving a request. There is a similar dispatch list, but that one is run in stateful mode.

It’s also possible to use snippets and templates to render HTML. It comes with the same limitation of not having access to session data. Additionally, all the ajax server-side functionnalities will not work as they rely on Scala closures stored in memory. But snippets and template are functional, and our website is built using them, and hosted on Heroku as well.

Configuration is also slightly different on Heroku. Heroku heavily uses environment variables to configure each application. This is how the database connection credentials are preferably communicated to the application. In contrast, Lift provides built-in support for .props file that contains properties used for configuration. In this project, we implemented a system that would check for a configuration variable in the environment variable first, and then default to the value found in the .props file. The possibility to set environment variables from the Heroku web interface makes it extremely painless to modify the configuration of the system.

Edit on May 29, 2016: If you want to check out the product we are building with Scala and Lift, we recently released SprayHere, a geo-localized platform to communicate with people around you. We are launching it locally, at EPFL in Lausanne. You can get the Android app in Google Play.