Folks,
I'm been working on the updates to the ESME REST APIs.

I've reduced the call cycle to something that looks like:

   1. A request is dispatched based on the URL
   2. The target of the dispatch returns a Box[T] where T is the type of the
   thing that will be calculated if it can be
      1. T might be Boolean, Int, User, etc.
      2. It's in a Box because it perhaps cannot be calculated (e.g., not
      enough permissions, etc.)
      3. The Box can be a Failure or even a FailureParam.  In the case of
      FailureParam, the param is the HTTP return code
   3. The result is put in an IntermediateAnswer along with a function that
   can convert from T to the expected HTTP response type (e.g., XML or JSON)
   4. The IntermediateAnswer is queried in order to build the actual
   response.

With a nice dose of implicit, the code becomes very clean:

  val dispatch: RetType = {
    case Req("rest" :: "status" :: Nil, "", GetRequest) => status()
    case Req("rest" :: "login" :: Nil, "", PostRequest) => login()
    case Req("rest" :: "logout" :: Nil, "", GetRequest) => logout()
    case Req("rest" :: "message" :: Nil, "", GetRequest) => getMsgs()
  }

And let's see some implementations:
  def status()  = User.currentUser ?~ "No Session" ~> 400

  def logout() = {
    User.logUserOut()
    true
  }

In status(), if there's no user logged in, we create a "No Session" error
message and return a 400.

In logout(), we just return true.

Now, the implicit magic comes from:
  implicit def boolToResp(v: Boolean, t: RequestedResponse): LiftResponse =
(v, t) match {
    case (v, XMLReqResponse) => new XmlResponse(<resp answer={v.toString}/>)
    case (v, JSONReqResponse) => JSONResponse(v)
  }

  implicit def userToResp(v: User, t: RequestedResponse): LiftResponse = (v,
t) match {
    case (v, XMLReqResponse) => new XmlResponse(v.toXml)
    case (v, JSONReqResponse) => JSONResponse(v.asJs)
  }

The code will automatically pick up these methods that convert from the
object type to the appropriate response type.  One of these "views" must
exist for each type that is returned from a dispatched method.

As I finish this stuff up, I'll roll it into some generic Lift classes.

Thanks,

David

-- 
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to