I'm working on a Clojure API but ran into this issue regarding Clojure's automatic "type-switching" between HashMap
and ArrayMap
when the item count inside the map changes.
Read doc: https://clojuredocs.org/clojure.core/array-map#example-57392e25e4b071da7d6cfd0c
Let's say I have a POST request like this:
(POST "/" []
:body [foo FooSchema]
(create-response ok {:message "foo!"}))
With FooSchema
defined like this:
(def ArrayMap clojure.lang.PersistentArrayMap)
(def Bar ArrayMap)
(s/defschema FooSchema
{:id s/Str
:bar Bar})
:bar
is sent as a javascript object that has structure like this:
{
id: 1,
fh: 1,
rdstr: "flying"
}
As stated in the documentation, if the :bar
object returns in the body
with less than 9 items then it'll yield ArrayMap, which works fine. Anyway, when the :bar
object scales and return more than 9 items, the request fails, return error:
(not (instance? clojure.lang.PersistentArrayMap a-clojure.lang.PersistentHashMap))
because :bar
was switched to HashMap
automatically (magically).
Vice versa, if I set the schema type of :bar
to HashMap
, then objects with less than 9 items doesn't work neither.
Anyway we can always force the type to HashMap
?
Both types are too specific. You should use a more general type, representing anything map-like. The obvious choice is clojure.lang.IPersistentMap
.