2
votes

I'm working with a REST API that represents an account with the following JSON:

{ "userName": "foo", "password": "bar", "emailId": "baz" }

I have a Clojure function to create an account that can be called like this:

(create-account :username "foo" :password "bar" :email "baz")

What I want to do is map the nice keys that create-account takes to the funky ones that the REST API expects. My current solution is this:

(def clj->rest {:username :userName
                :email :emailId})

(apply hash-map
       (flatten (map
                 (fn [[k v]] [(or (clj->rest k) k) v])
                 args)))  ;; args is the arguments to create-account, as above

Is there a more idiomatic way to accomplish this?

3

3 Answers

11
votes
(clojure.set/rename-keys args clj->rest)

... mimics your solution, producing ...

{:emailId "baz", :userName "foo", :password "bar"}

I take it you've worked out how to change this into the required JSON.

4
votes

You may write a simple helper function to map all keys with given mapping function:

(defn kmap [f m]
  (into {} (map #(update-in % [0] f) m)))

So, now you'll be able to easily map your arguments:

(def clj->rest {:username :userName
                :password :password
                :email :emailId})

(kmap clj->rest args)
1
votes

Looks good, just change (apply hash-map (flatten ... to (into {} ... for more idiomatic code.