happs -> happstack?

23 views
Skip to first unread message

Martin Clausen

unread,
Mar 12, 2016, 6:08:09 PM3/12/16
to HAppS
I am new to happs(tack) and Haskell in general, and could need some help converting a very simple happs example to happstack.

I have a SO question here which has the relevant code. It has been up for some time without a viable answer and I was hoping someone on this list might be able to help.

Cheers

Martin

Jeremy Shaw

unread,
Mar 14, 2016, 10:46:55 PM3/14/16
to HAppS
Hello,

I suspect this is part of the problem. In the original you had: 

main :: IO ()
main = do simpleHTTP [dir "contractEx"
                        [withData $ \(ExContr t) ->
                           [anyRequest $ liftIO $ liftM toResponse =<< renderEx (ExContr t)]
                        ,anyRequest $ ok $ toResponse renderExDefault]
                     ,fileServe ["Contracts.html"] "public" -- fileserving


   ]
Note that the 'withData' function takes a list of handlers -- and in that list there is only one handler.

The withData route will only match if valid data is submitted. If that route fails to match, then the next route is tried. In this case the next route is the second anyRequest route which will just render the default renderExDefault.

In the Happstack version:

main :: IO ()
main = do
  simpleHTTP (nullConf { port = 80 }) $ msum [
         dir "contractEx" $ withData $ \(ExContr t) -> msum $ [
                anyRequest $ fmap toResponse $ liftIO $ renderEx (ExContr t)
              , anyRequest $ toResponse renderExDefault
              ]
       , serveDirectory DisableBrowsing ["Contracts.html"] "public"
       ] 
Both anyRequest routes are guarded by the 'withData' function. So, neither will be called unless there is valid data. Additionally, since the first anyRequest line should always match, the second anyRequest will never be called.

The could should probably be something like:

main :: IO ()
main = do
  simpleHTTP (nullConf { port = 80 }) $ msum [
         dir "contractEx" $ msum $ [
                withData $ \(ExContr t) -> anyRequest $ fmap toResponse $ liftIO $ renderEx (ExContr t)
              , anyRequest $ toResponse renderExDefault
              ]
       , serveDirectory DisableBrowsing ["Contracts.html"] "public"
       ] 

So that withData is only used to guard the first anyRequest.

You can read more about routing in this chapter:


The FromData stuff is not used that commonly anymore. You can read about a more modern method of handle request data in this chapter:


- jeremy


--
You received this message because you are subscribed to the Google Groups "HAppS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to happs+un...@googlegroups.com.
To post to this group, send email to ha...@googlegroups.com.
Visit this group at https://groups.google.com/group/happs.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages