What is idiomatic Clojure for this simple logic?

clojure, idioms

Solution

I think the biggest problem with your function is that it tries to handle three things at once:

- Checking if username and password are valid for a user (`credential-fn` and `verify-pw`)

- Cleaning up the record data `(dissoc user-record password)`

- Building a Ring response map (`{:status 401}` vs. `{:status 200 :body user-record}`)

I would consider splitting your code into two separate functions:

(defn authenticate
  [username password]
  (and (verify-pw password) 
       (dissoc (credential-fn username) :password)))

(defn login
  [username password]
  (if-let [user-record (authenticate username password)]
    {:status 200 :body user-record}
    {:status 401}))

Problem

I have written a simple contrived auth function in Clojure and it doesn't feel very idiomatic to me at all. Is there a better way of writing this: ``` (defn auth [username password] (let [user-record (credential-fn username)] (if (and user-record (verify-pw password)) (let [user-record (dissoc user-record :password)] {:status 200 :body user-record}) {:status 401}))) ``` I thought it might be possible to get rid of the `if` by using `if-let`, but the `if` is doing a boolean check and I need to bind the `user-record`? Stuck! NOTE: the `dissoc` is removing the password from `user-record` so it's not returned in the body.

Original source