I cannot seem to implement a simple counter in my session. I would like something as simple as :counter in my request (or perhaps it must be in :session) to increment on the execution of any route. The :counter is incremented once to 1 but increments no further on refresh or visit to any other route. I feel I am missing something very simple.
It might be more intuitive to think of middleware like: `(defn wrap-identity [handler] (fn [request] (let [response (handler request)] response)))`
To update the session, you need to attach the updated session to the :session key on the response.
Does that help make things clear?
Your example is very clear. This also helped me, will leave here: https://gist.github.com/krisleech/893f396d864c75fde9e6933c9ac0cb09
So, to update session, I would do something like:
(defn wrap-identity [handler]
(fn [req]
(let [resp (handler req)
updated-session (assoc (-> req :session) :random-thing "whatever")]
(assoc resp :session updated-session)))I believe I just rubber-ducked myself! (It really does work!) duckie Never mind, still stuck!
Here is my update-counter fn:
(defn update-counter [handler]
(fn [req]
(handler
(if (-> req :session :count)
(let [count (-> req :session :count)
updated-session (assoc (:session req) :count (inc count))]
(-> req
(assoc :session updated-session)
(assoc :does-this-work? "yes")))
(assoc req :crazy "town")))))And my app and its middleware:
(def real-app
(-> (fn [req] (app req))
wrap-anti-forgery
wrap-special
update-counter
wrap-session))
; my jetty server
(defn -main [& [port]]
(let [port (Integer. (or port (env :port) 5010))]
(jetty/run-jetty
(fn [req] (real-app req))
{:port port :join? false})))Your update-counter middleware is updating the value on the way in, not on the way out
I am using Compojure. I guess I don't understand where with middleware to modify or update the session in the response.
If I want to apply my wrapper to all routes (just to keep it simple for now) but need to check current count on the request, don't I still wrap my real-app?
I'm having trouble finding documentation that lays it out clearly.
You are updating the session value being passed to your handler, but not including an updated session in the response that flows back out of the handler, back out of your middleware and back to the session middleware
(-> req (assoc :session updated-session) ?
Isn't the above the modified response flowing out?
No
Reqs flow in resps flow out
Where are responses passed in a Compojure route?
Rather, I know the answer to that, but if I wanted to modify the responses for all routes -- I don't understand where the middleware for that goes.
same middleware does it
Are you saying I need to pass something like res? I don't understand, I thought the output of these handles is the response, which is simply a request modified.
If there is a resource worth reviewing to better understand the concept, I will appreciate any pointers. Thanks very much
a handler is a function that takes a request and returns a response
a middleware takes a handler and returns a handler
update-counter is a middle
inside the middleware is the new handler it defines
the new handler update-counter creates messes around with the session in the request before passing it to the original handler that was passed to update-counter and then returns the result of that original handler unchanged
you need to ensure that the session is set with the updated count is added to the result of the original handler before returning it
Thank you for taking the time to explain. I will try again