Tools

Lift code is easy to read and maintain. Lazy loading, parallel execution, simple push mechanics, and REST support are just a few of Lift's stand-out benefits.

Creating a REST Service with Lift

Lift provides helpers that make it easy to create a REST service with just a few lines of code. I'll provide a simple example that doesn't consider security issues. However, the required authentication checking can be added with just a few additional lines of code. This sample REST service involves games: It must list all the games and a specific required game by its ID. The restapi/game/list URI must display all the games, and if there is a long parameter with an ID such as restapi/game/list/1, the service must find this game by ID and return the results.

The following listing shows the code for a new GameInformation.scala file that defines the GameInformation case class and a Singleton object with the same name. Notice that the code is included in the code.model package, which is the default package for models based on the rules I defined in Boot.scala in the previous article. You must place the file in src/main/scala. The GameInformation object defines games as a List of three GameInformation instances to include sample data to make it easy to test the REST service.

The find method returns the a Box[GameInformation] with a GameInformation instance when one element in the gamesList matches the ID received as a parameter.

Now that I have the necessary model, I can use it in a Singleton object named GameRest, which holds the code to process and respond to the API calls. GameRest extends RestHelper and makes use of Scala's pattern matching to match incoming HTTP requests, extract the required values as part of the pattern matching process, and return the results with the necessary conversions. Notice that the code is included in the code.lib package, which is the default package for a REST API in Lift. You must place the file in src/main/scala.

When Lift receives an HTTP request, it tests a PartialFunction[net.liftweb.http.Req, () => Box[net.liftweb.http.LiftResponse] to check whether it is defined. If Lift finds a match, it takes the resulting function and applies it to get a Box[net.liftweb.http.LiftResponse], then returns it when it is full.

The serve method defines the request handlers:

restapi/game/list with no additional values calls the listAllGames method.

restapi/game/list/{id}, where {id} is a long value with the desired id calls the listGame method with the received id as a parameter. For example, restapi/game/list/2 calls listGame(2).

The anyToJValue method is a helper method that creates JSON from case classes. The definition of the request handlers and its pattern matching is easy to understand and maintain, as shown in the following lines:

Finally, it is necessary to make Lift include the GameRest object in the request processing pipeline. Thus, you must make a small change in Boot.scala. Just add the following import:

import code.lib. ...

Then, add the following lines within the Boot.boot method:

// Make Lift include the GameRest object in the request processing pipeline
LiftRules.dispatch.append(GameRest)

As you might notice, it isn't necessary to list the REST URLs in Lift's SiteMap. The simple REST API is ready to process requests. The following request, http://localhost:8080/restapi/game/list, generates the response shown in the listing with all the games retrieved by the listAllGames method:

The following request, http://localhost:8080/restapi/game/list/4, results in a call to the listGame method with 4 as the id value. There is no game that matches this idvalue; the following lines show the result:

Conclusion

Lift has a very active community and it is worth taking a look at the modules it has written that provide extra features such as PayPal and Open ID integration. Before you start working on any integration or additional feature, check the information for the modules listed on https://www.assembla.com/spaces/liftweb/wiki/Modules.

The Lift framework takes advantage of many helpful features in the Scala programming language, and the code is easy to read and maintain. Once you make the shift from MVC to Lift's ViewFirst model or after you work with a few REST APIs based on Lift, it is difficult to go back to MVC frameworks without missing the wonders of dozens of Lift's features.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!