cookiesclojurecompojure

how to set and get cookie with compojure?


Created project using lein new compojure project-name and have the server referencing (wrap-defaults project-name site-defaults).

Inside my handler I am calling controllers and passing the params to those controllers. Project structure:

handler.clj ;; ring accesses def app
controllers/app.clj ;; where route params are sent
example: (GET "/signup" {params :params} (controller-app/signup params))

So the issue I am having is I cannot figure out how to get or set cookies from the controllers file. Things I have tried:

Any help would be much appreciated. There is not much documentation on this so unfortunately the problem has taken a fair amount of time.


Solution

  • Finally was able to solve it by brute force. It's no joke when people say the documentation for Clojure is pretty sparse. A couple of notes on ring:

    Now onto how to do this:

    Here you pass the cookie to the controller from inside your handler. Cookies are available by default if you used "lein new compojure app-name" to create your app. I had to read the source code to figure this out.

    default namespace (app-name/handler.clj) -

    (ns some-namespace.handler
      [compojure.core :refer :all]
      [compojure.route :as route]
      [ring.middleware.defaults :refer [wrap-defaults site-defaults]
      [app-name.controllers.home :as home-controller))
    

    Your app routes (app-name/handler.clj) -

    (defroutes app-routes
      (GET "/" {cookies :cookie} (home-controller/home cookies)))
    

    Here is how you set the cookie itself (app-name/controllers/home.clj).

    (ns app-name.controllers.home)
    
    (defn home [cookies]
      {:headers {"Content-Type" "Set-Cookie"},
       :cookies {"cookie-name" {:value "cookie-value", :path "/"}},
       :body "setting a cookie"})
    

    Bottom of handler.clj using default wraps for specified routes (app-name/handler.clj)

    (def app
      (wrap-defaults app-routes site-defaults ))
    

    This was a very simple problem that turned out to be far more complex. It took me 3 days to figure all of the above out. I am new to Clojure/Ring/Compojure but this has been the worst experience I have had yet programming.

    It's really a problem of just enough abstraction to become dangerous (so basically nothing is obvious). Libraries like Ring REALLY need to be better documented and over explained if wider adoption is wanted.

    Anyways, I hope this helps someone.