GET and POST data

GET data is data attached to an http request via the url string. In the job board app, an example of this is tphyahoo's profile, where the user is specified on the url string. Another example is fetching a particular job.

POST data is data attached to a request after submitting a form. One place this is used is in the registration process. Once you have a user created, you can also see POST in action by editing your profile or creating jobs.

HAppS deals with GET and POST data similarly.

Let's look at how tphyahoo's profile gets displayed.

Controller.hs: ... , dir "viewprofile" [ methodSP GET \$ userProfile rglobs ] ...

using dir and methodSP as above is a common pattern. dir pops the head element of the path array ["viewprofile"], resulting in an empty array. methodSP checks that the path array is empty and that the method is GET. If so, control is passed to the next sp: userProfile rglobs, which is in another module.

ControllerGetActions.hs:

data UserNameUrlString = UserNameUrlString {profilename :: String}
instance FromData UserNameUrlString where
  fromData = liftM UserNameUrlString (look "user" `mplus` return "")
userProfile rglobs =
  withData \$ \(UserNameUrlString user) ->
   [ ServerPartT \$ \rq -> do .....

*Main> :t withData :: FromData a => (a->[ServerPartT IO Response]) -> ServerPartT IO Response

The above is the main pattern for processing GET or POST data in happs.

First, you decide what argument type withData should accept. This might be a datatype you have already defined, like User or Job, which already plays a major role in the app. Or it could be an ad-hoc datatype which is only used this once, in the form processing. Whatever the case you declare that data type an instance of FromData, and define how it should grab data attached to the request. In this case, UserNameUrlString takes one argument, so we use LiftM -- for two args we would use LiftM2, three args LiftM3 etc. To get that one arg, we look for a request GET variable named "user" and if we don't find it we use a reasonable default, in this case the empty string. The result is a value of type UserNameUrlString which gets passed to the ServerPartT handler in the userProfile function.

Another use is... (pagination. now... sleeep.....)