July 6, 2010
This post discusses the session API as present in Yesod 0.4. This version has not been released yet, but you can see the Haddocks online. The API is not much different from previous versions, but the names have changed a bit.
Most web frameworks provide some notion of user sessions, where you can store small bits of information for each user. In the case of Yesod, we use the clientsession package (also written by yours truly) to store data in an HTTP cookie. While this might sound insecure and inefficient at first, it's not:
- All data is hashed, encrypted and base64-encoded before being placed in the HTTP cookie.
- You shouldn't be storing large amounts of data in the cookie, so the bandwidth overhead shouldn't be large.
- Production sites should be serving their static data from a separate domain name, meaning the cookie bandwidth hit won't apply to them.
- By storing the data in a client session, we avoid a database lookup for each request, which can be very expensive.
- Currently, sessions are not compressed, though this is a feature easily added in the future if it turns out to be beneficial.
Like most frameworks, the sessions are simple key-value stores. There are three basic operations on a session:
- lookupSession gets a value for a given key.
- setSession sets a new value, or replaces an existing value.
- deleteSession clears the value in a session, so that it does not appear in the next request.
Please note that the setSession and deleteSession functions do not affect the outcome of a call to lookupSession within a single request. In other words:
do val1 <- lookupSession "key" setSession "key" "newvalue" val2 <- lookupSession "key" -- val1 == val2, not "newvalue"
Messages are built on top of sessions. The situation is a common one in web development: the user performs a POST request, you make a change, and want to simultaneously tell the user that the request suceeded and redirect them to a new page. Yesod provides a pair of functions to make this very easy:
- setMessage stores a value in the session.
- getMessage both reads the value most recently put into the session, and also clears that old value.
In my projects, I will often put a call to getMessage in the defaultLayout function and know that any messages I set with setMessage will be displayed on the next page the user views.
Not to be confused with a horror film, this concept is used internally in the Yesod authentication module. Simply put, let's say a user requests a page that requires authentication. Clearly, you need to send them to the login page. A well-designed web app will then send them back to the first page they requested. That's what we call the ultimate destination.
- setUltDest sets the ultimate destination to the given route.
- setUltDest' is a variant of setUltDest that sets the ultimate destination to the current route.
- setUltDestString is the same thing, but uses a string instead of a type-safe URL. Can be useful if you want to send a user to another site after authentication.
- redirectUltDest sends the user to the ultimate destination currently in his/her session and clears that value from the session.