Keith
> --
> You received this message because you are subscribed to the Google Groups "Compojure" group.
> To post to this group, send email to comp...@googlegroups.com.
> To unsubscribe from this group, send email to compojure+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/compojure?hl=en.
>
Keith Lancaster
klancas...@acm.org
Compojure is a far lighter framework than Rails, and doesn't mandate a
particular library for handling sessions. Ring comes with session
handling middleware, but there are also alternative session handling
libraries like Sandbar.
I'll focus on Ring's session middleware. The session is encoded in the
request map under the :session key. Here's an example route that uses
the session:
(GET "/" {session :session}
(str "Hello " (session :user)))
To write to the session, you need to add the updated session to the
response map under the :session key. Here's an example route that sets
the session:
(GET "/set" {session :session, params :params}
{:session (assoc session :user (params :user))
:body "Session set"})
To wrap your routes in the session middleware, first load in the
appropriate namespace:
(use 'ring.middleware.session)
And then use wrap! to wrap your routes in the session middleware:
(wrap! app :session)
Putting it all together, you'll have something like:
(ns session-test
(:use compojure.core, ring.middleware.session, ring.adapter.jetty))
(defroutes app
(GET "/" {session :session}
(str "Hello " (session :user)))
(GET "/set" {session :session, params :params}
{:session (assoc session :user (params :user))
:body "Session set"})
(wrap! app :session)
(run-jetty app {:port 8080})
However, that's somewhat of a clunky way to use sessions. Usually,
you'll wrap your session handling in some manner of middleware. For
instance:
(declare *user*)
(defn wrap-user [handler]
(fn [{session :session :as request}]
(binding [*user* (session :user)]
(handler request))))
Then, if you wrap your app in wrap-user as well as wrap-session,
you'll get the *user* binding bound to a value in the session:
(defroutes app
(GET "/" []
(str "Hello " *user*))
(GET "/set" {session :session, params :params}
{:session (assoc session :user (params :user))
:body "Session set"})
(wrap! app :user :session)
(run-jetty app {:port 8080})
In many ways, the ring session handling middleware is less concise
than something you'd find in Rails, but it has the advantage of being
easily manipulated by middleware. Compojure emphasises a composition
of small components, rather than a monolithic design like Rails.
Although, if you want session handling that's a little easier to use
manually, the wrap-stateful-session middleware in Sandbar looks a nice
alternative.
- James