2010-07-02

REST with Scala's Lift framework. Part 2 - POST

In my previous post I explained how to handle GET requests with Scala’s Lift framework in a RESTful way.

In this post I will show you how to...


Handle POST in Lift using REST


Which is a bit different than handling GET, because you expect an actual object to be coming your way along with the request!

I am going to work with the same project as in Part 1. If you haven’t read it yet, you might want to do it now to make things clear.

(I already did that for Spring 3, you may want to take a look: REST with Spring 3: POST.)


Retrieve the request


package bootstrap.liftweb

import me.m1key.rest.DogsRestService
import net.liftweb.http._

class Boot {
  def boot {
    // ...

      LiftRules.statelessDispatchTable.append {
          // ...
          case request @ Req(List("rest", "dogs"), _, PostRequest) =>
              () => DogsRestService.addDog(request)
      }
  }
}

It looks a bit different, because you assign the request to a value named also request (of type Req) and then you pass it to the service. You also narrow it down to POST requests with PostRequest.


Processing the request


This is how you process the request. It’s not quite neat.

    def addDog(request: Req): Box[LiftResponse] = {
      var dogName = ""
      request.xml match {
            case Full(<dog>{parameters @ _*}</dog>) => {
              for(parameter <- parameters){
                  parameter match {
                      case <name>{name}</name> => dogName = name.text
                      case _ =>
                  }
              }
              val dog = new Dog("2", dogName) // Normally you'd assign a unique ID
              Log.info("Creating a dog with name: " + dog.name)
              return Full(InMemoryResponse(dog.toXml.toString.getBytes("UTF-8"), List("Content-Type" -> "text/xml"), Nil, 200))
          }
          case _ => Log.error("Invalid request");
              Log.error("Request: " + request);
              Log.error("Request.xml: " + request.xml);Full(BadResponse())
      }
  }

If the request is correct, then we acquire the dog’s name and we create a new dog using that name. We then return it with HTTP code 200 (OK).

If the request is incorrect (for instance, no XML with a dog in it), then we use Lift’s BadResponse and pack it in a Full. That gives the user HTTP code 400.


Summary


Handling RESTful POST requests in Lift 1.0 is not as comfortable as it is with Spring 3. I’m looking forward to seeing Lift 2.0 improvements in that matter.

Download source code for this article

No comments:

Post a Comment