reitit 2024-05-10

Hi, I'm trying to use reitit+malli for request validation and coercion, but can't get the default values option to work. Code in thread Any help would be much appreciated πŸ™

My code:

["/tasks" {:get {:parameters {:query schemas/GetTasksRequest}
                 :coercion   schemas/GetTasksRequest ;; tried with and without this line
                  :handler    (fn [request]
                                  {:status 200
                                   :body   (:params request)})}}]

(defn- ->router [routes]
  (ring/router
    routes
    {:data     {:coercion   (reitit.coercion.malli/create
                              (-> reitit.coercion.malli/default-options
                                  (assoc-in [:transformers :string :default]
                                            transformer/custom-string-transformer)
                                  (merge {:error-keys   #{:humanized}
                                          :encode-error humanized-response})))
                :muuntaja   muun/instance
                :middleware [;; query-params & form-params
                             parameters/parameters-middleware
                             ;; content-negotiation
                             muuntaja/format-negotiate-middleware
                             ;; encoding response body
                             muuntaja/format-response-middleware
                             ;; exception handling
                             exception/exception-middleware
                             ;; decoding request body
                             muuntaja/format-request-middleware
                             ;; coercing response bodys
                             coercion/coerce-response-middleware
                             ;; coercing request parameters
                             coercion/coerce-request-middleware]}}))

in transformers ns:
(defn singleton->vector [x]
  (if (string? x)
    (if (vector? x) x [x])
    x))

(def custom-string-type-decoders
  (assoc (mt/-string-decoders) :vector singleton->vector))

(def custom-string-transformer ;; need this to allow vectors
  (mt/transformer
    (mt/strip-extra-keys-transformer)
    {:name     :string
     :decoders custom-string-type-decoders
     :encoders (mt/-string-encoders)}
    (mt/default-value-transformer {::mt/add-optional-keys true})))

in schemas ns:

(def GetTasksRequest
  (m/schema
    [:map
     [:parent_id {:default "root" :optional true} ParentId]
     [:page {:default 1 :optional true} pos-int?]
     [:tag_id {:optional true} TagIdVector]
     [:from_priority {:default 1 :optional true} Priority]
     [:to_priority {:default 10 :optional true} Priority]
     [:status {:default "Not Started" :optional true} [:vector StatusVector]]
     [:people {:optional true} UserIdVector]
     [:start_date {:default (LocalDate/now) :optional true} Date]
     [:end_date {:default (LocalDate/now) :optional true} Date]
     [:order_by {:default "desc" :optional true} OrderBy]
     [:order_key {:default "date" :optional true} OrderKey]]))
If I try to do it in the REPL it works:
(let [tr transformer/custom-string-transformer]
  (m/decode
    schemas/GetTasksRequest
    {}
    tr))
=>
{:order_by "desc",
 :order_key "date",
 :page 1,
 :end_date #object[java.time.LocalDate 0x6d926cef "2024-05-10"],
 :start_date #object[java.time.LocalDate 0x7ed9b28d "2024-05-10"],
 :status [["Not Started"]],
 :parent_id "root",
 :to_priority 10,
 :from_priority 1}
So I think the problem is in my reitit configuration.

Hi folks. I am having the exact same problem that @assous.gili had back in May. Does anyone have any pointers as to how to make local date coercion work with Malli?

could you post some code? have you included malli.experimental.time/schemas in your registry?

(def router
  (ring/router
    routes
    {:data                        {:muuntaja   muuntaja/instance
                                   :coercion   (reitit.coercion.malli/create
                                                 (merge reitit.coercion.malli/default-options
                                                        {:options {:registry (merge
                                                                               (m/default-schemas)
                                                                               (met/schemas))}}))
                                   :middleware defaults-middleware
                                   :defaults   (-> api-defaults
                                                   (assoc :exception true))}
     :reitit.middleware/transform identity #_reitit.ring.middleware.dev/print-request-diffs}))
Hi @joel.kaasinen. Sure, this is the code for my router. I added malli.experimental.time/schemas directly into the :coercion map

what does the reitit definition look like for that path that's not working? what data are you sending? what results are you seeing and what did you expect?

Hi! I went to install the new reitit-openapi and saw that its Maven group is fi.metosin rather than plain metosin like the others. I'm just curious about the difference there - should we expect that other Reitit modules will also switch to this new coordinate?

It comes from this requirement I believe (may be wrong!): https://github.com/clojars/clojars-web/wiki/Verified-Group-Names

πŸ‘ 1

Bummer that new libraries for existing groups couldn't be grandfathered in, that sticks out like a sore thumb (and breaks alphabetical sorting for folks who care) 😞

Sticks out … until the older libraries also migrate over. Maybe that’s on the roadmap?

Thanks for the clarification. I think something like this could have helped avoid some confusion on my part: https://github.com/metosin/reitit/pull/681

πŸ”₯ 1