Fork me on GitHub
#reitit
<
2024-03-10
>
Joseph Graham04:03:39

How does one handle coercion in-case of a posted list? Essentially the requests may contain one or more task_id . Ring handles this by normally providing a list of strings. But the special-case where there is only one causes a problem because then I just get a string (not in a list). I need to coerce it to always be a list of ints irregardless whether it started as a list of strings or a singular string.

Joseph Graham07:03:28

I came up with a convoluted fix but needless to say it's not ideal: • I add an extra hidden "task_id" input field containing a dummy value. this forces it to always be a list • I wrote a middleware to strip the dummy value back out again

Joseph Graham06:03:12

I have made another attempt at this:

(s/def ::int int?)

(s/def ::ints-list
  (s/conformer conform-to-vector
               (s/coll-of int? :kind vector?)))
However I'm still getting a plain int (not wrapped in a vector).

Joseph Graham05:03:13

Solved. I had to write new middleware to supplement the existing co-ersion:

(defn keys-with-list-values
  "this function helps parsing the ring request middleware"
  [kv-map]
  (for [[k v] kv-map
        :when (clojure.string/includes? (name v) "-list")]
    (name k)))

(defn wrap-vector
  "for some reason the coercion does not update these to vectors. so we do it
  ourselfes"
  [handler mapkey]
  (fn [{{{{{[coercion-info] :form} :parameters} :post} :data} :reitit.core/match
        :as request}]
    (prn coercion-info)
    (let [form-params (mapkey request)
          transform-keys (keys-with-list-values coercion-info)
          transformed-params (reduce (fn [params key]
                                       (if (contains? params key)
                                         (update params key conform-to-vector)
                                         params))
                                     form-params
                                     transform-keys)
          updated-request (assoc request mapkey transformed-params)]
      (handler updated-request))))