Internally, clojure.data.json/write
calls name
on instances of clojure.lang.Named
wherever it encounters them, which strips the namespace:
(json/write {:foo/bar :baz/bork}
*out*
:escape-slash false)
;; => {"bar":"bork"}
The clojure.data.json/write
function provides the options :key-fn
and :value-fn
for changing this (or any other) behavior on map keys and values:
(json/write {:foo/bar :baz/bork}
*out*
:escape-slash false
:key-fn (comp str symbol)
:value-fn (fn [k v] (if (instance? clojure.lang.Named v)
(str (symbol v))
v)))
;; => {"foo/bar":"baz/bork"}
But it doesn't work in other contexts (and, per the docstring, is not meant to):
(json/write {:foo/bar [:baz/bork]}
*out*
:escape-slash false
:key-fn (comp str symbol)
:value-fn (fn [k v] (if (instance? clojure.lang.Named v)
(str (symbol v))
v)))
;; => {"foo/bar":["bork"]}
The only available mechanism for changing this behavior in all contexts is to extend the JSONWriter
protocol, but this would change the behavior globally. It would be helpful if an option were available to preserve namespaces in all contexts, or to override how a given type is written without changing it globally.