Use Session Snaplet

9 views
Skip to first unread message

Haisheng Wu

unread,
Jan 11, 2012, 1:35:21 AM1/11/12
to sn...@snapframework.com
Hello All,
  Basically I'm practice the session snaplet and got one question.

I define the App as:
data App = App                                                                                                                                                         
    { _heist      :: Snaplet (Heist App)                                                                                                                               
    , _startTime  :: UTCTime                                                                                                                                           
    , _appSession :: Snaplet SessionManager                                                                                                                            
    }

and init it as:
app :: SnapletInit App App                                                                                                                                             
app = makeSnaplet "app" "An snaplet example application." Nothing $ do                                                                                                 
    sTime <- liftIO getCurrentTime                                                                                                                                     
    h <- nestSnaplet "heist" heist $ heistInit "resources/templates"                                                                                                   
    s <- nestSnaplet "session" appSession $ initCookieSessionManager "log/site-key.txt" "myapp-session" (Just 600)                                                     
    addRoutes routes                                                                                                                                                   
    return $ App h sTime s

Then in the `index` handler I set a session value:
with appSession $ withSession appSession $ setInSession "user_age" "32"

Afterwards in the `echo` handler I like to get the value:
sv <- with appSession $ getFromSession "user_age"

It all works well.
And my question is in the `index` handler when I put something into session, I have to do:
  `with appSession $ withSession appSession $...`
The appSession is used twice and everytime I'd like to play session operation I need `with appSession`.

I think I'm able to make couple of util functions to be a little clear.
But I still wondering whether I'm using the session snaplet incorrectly?
In other words, do we have any type class like `hasHeist` or `HasMongoDBState` to make it simpler?

Thanks a lot!

-Simon

Ozgun Ataman

unread,
Jan 11, 2012, 2:37:51 AM1/11/12
to Haisheng Wu, sn...@snapframework.com
Hey there,

In your example, "with session" zooms into the session snap let's state. withSession, on the other hand, makes sure changes to session state are committed.

withSession is designed to flexibly wrap handlers that change session data somewhere along their computation. It is meant for things like:

complexHandler = withSession session $ do
  with session $ getFromSession ….
  with heist $ doSomething
  with db $ doSomething
  with session $ setInSession ….

the Handler b v a type flexibility makes sure the above works and withSession itself ensures changes to session data are committed.

Perhaps we can add a 

withSession' :: Lens b (Snaplet SessionManager) -> Handler b SessionManager a -> Handler b v a
withSession' session = withSession session . with session

function to simplify the use case you've mentioned and avoid using 2 functions with the session lens. A typeclass may also be possible, but I haven't given it much thought so far.

Hope that helps.

Cheers,
Oz


Reply all
Reply to author
Forward
0 new messages