Normally, Lift will look for a "view" that satifying an HTTP request. A view is an XHTML page or segment of a page with special <lift:xxx> processing instructions in it (e.g., an instruction to embed a controller, an instruction to surround the XHTML with another template, etc.) However, in certain cases, for example, when you want to satisfy a Web Services (REST) request, you can use Scala's pattern matching to intercept a request and service it.

It's easy to "serve" incoming HTTP requests. Using Lift's RestHelper class. For example, you can serve "/webservices/all_users" as a JSON request as:

  serve {
    case "webservices" :: "all_users" :: _ JsonGet _ =>
      AllUsers(User.findAll()).toJson
  }

And we can serve the same request if it's an XML request:

  serve {
    case "webservices" :: "all_users" :: _ XmlGet _ =>
      AllUsers(User.findAll()).toXml
  }

If you have a request (in the case of this example, servicing both a POST and a GET for /webservices/add_user), then service the request and include a function to convert the response into either JSON or XML:

  serveJx {
    case Req("webservices" :: "add_user" :: _, _, rt) if rt.post_? || rt.get_? =>
      addUser()
  } { // How do we convert a UserInfo to either XML or JSON?
    case (JsonSelect, u, _) => u.toJson
    case (XmlSelect, u, _) => u.toXml
  }

And the addUser() method looks like:

  def addUser(): Box[UserInfo] =
    for {
      firstname <- S.param("firstname") ?~ "firstname parameter missing" ~> 400
      lastname <- S.param("lastname") ?~ "lastname parameter missing"
      email <- S.param("email") ?~ "email parameter missing"
    } yield {
      val u = User.create.firstName(firstname).
      lastName(lastname).email(email)

      S.param("password") foreach u.password.set

      u.saveMe
    }

Note that if the firstname parameter is missing, a 400 response with the message "firstname parameter missing" message in the body will be returned. If the lastname parameter is missing, a 404 will be returned with "lastname parameter missing" message in the body.