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