Search code examples
clojure

how to apply key-decode-fn only to top level keys while json unmarshaling using metosin


I've a requirement where I can decode only keys.

consider the below example -

(require '[jsonista.core :as json])
(import
 (com.fasterxml.jackson.core JsonFactory$Feature)
 (com.fasterxml.jackson.databind ObjectMapper)
 (com.fasterxml.jackson.datatype.joda JodaModule))

(def s "{\"name\":\"person1\",\"book\":\"Demo Book\",\"hash\":{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}}")

(def ^ObjectMapper object-mapper
  (let [obj-mapper (json/object-mapper {:decode-key-fn true :modules [(JodaModule.)]})]
    (doto obj-mapper
      (-> .getFactory (.disable JsonFactory$Feature/USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING)))
    obj-mapper))

(json/read-value s object-mapper)

The output I would like to get is

{:book "Demo Book", :name "person1", :hash {"key3" "value3", "key2" "value2", "key1" "value1"}}

In the json above, the top level is converted to keys and nested are not converted to keys but kept as string.

:decode-key-fn true make all keys and without :decode-key-fn true all keys are strings which is not I want. How can I achieve the same?


Solution

  • If you want to convert all keys and only on the top level, you can use update-keys:

    (-> (json/read-value s object-mapper)
        (update-keys keyword))
    

    With that, set :decode-key-fn in object-mapper to false.