Newbie enjoying Clojure a lot here. So, I have an HTTP route:
(POST "/login" request (post-login request))
here, "request" is a map with a lot of http things inside. And the "post-login" function:
(defn post-login
;; Login into the app
[{{email "email" password "password"} :form-params session :session :as req}]
(let [user (modusers/get-user-by-email-and-password email password)]
;; If authenticated
(if-not (nil? (:user user))
(do
(assoc (response/found "/")
:session (assoc session :identity (:user user)) :flash "Bitte schön!"))
(assoc (response/found "/login") :flash "Etwas stimmt nicht mit deinem Zugriffsprozess"))))
but I don't understand how "request" is being destructuring. How "email" and "password" are now available inside the function?, and what ":as req" means? Is there a name to this "technique"?
If it's still not clear from the comments, here's a quick answer:
Your post-login
function receives a single argument which is a map representing HTTP request. This argument is stored in req
with the help of the special :as
keyword.
So (defn post-login [req] ...)
and (defn post-login [{:as req}] ...)
are exactly the same.
A (one) way that map destructuring works is that you provide a map key on the right side and the thing to which it should be bound on the left side, e.g. [{form-params :form-params :as req}]
. Now the :form-params
key in req
map will be bound to the form-params
symbol available inside the function body.
Things get more interesting when you do "nested" destructuring. In your case, [{{email "email" password "password"} :form-params :as req}
just means that :form-params
key inside the request will be bound to {email "email" password "password"}
which again is a destructuring itself. Eventually, the "email"
key in :form-params
will be bound to the email
symbol and the same for password
.
As before, if you need access to the whole request (not just some params inside it) you may get that via :as
.
Note: there's an alternative syntax which you can use (a kind of shortcut):
[{{:strs [email password]} :form-params session :session :as req}]