metosin / reitit

A fast data-driven routing library for Clojure/Script

Home Page:https://cljdoc.org/d/metosin/reitit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Coercer fails to compile?

jarcane opened this issue · comments

I've been working on some code to generate reitit routes based on malli schemas, and wanted to write some tests to make sure the schema checking/coercion is done properly.

We've hit a snag though, where I don't actually seem to get a coercer from compile-request-coercers, just a nil, so calling coerce! just returns a nil as well.

We generate a set of routes that looks like this:

(def expected-api
  [[(str "/test-model")
    {:coercion reitit.coercion.malli/coercion}
    ["/" {:get {:responses {200 [TestModel]}}
          :post {:parameters {:body TestModel}
                 :responses {200 TestModel}}}]
    [(str "/:id")
     {:get {:parameters {:path [:id :int]}
            :responses {200 TestModel}}
      :patch {:parameters {:path [:id :int]
                           :body TestModel}
              :responses {200 TestModel}}
      :delete {:parameters {:path [:id :int]}
               :responses {200 "OK"}}}]]])

Turn it into a router like so:

(def router (ring/router generated-api
                         {:validate rrs/validate
                          :compile coercion/compile-request-coercers}))

(defn match-by-path-and-coerce! [path]
  (when-let [match (r/match-by-path router path)]
    (assoc match :parameters (coercion/coerce! match))))

Now according to the docs, if I match on one of these paths I should get a coercer under the :result key in the match but ... I don't.

(r/match-by-path router "/test-model/4")
{:template "/test-model/:id",
 :data
 {:coercion #Coercion{:name :malli},
  :get
  {:parameters {:path [:id :int]},
   :responses {200 [:map [:id :int] [:name :string] [:cat? :boolean] [:datetime [:or :string :int]]]}},
  :patch
  {:parameters
   {:path [:id :int], :body [:map [:id :int] [:name :string] [:cat? :boolean] [:datetime [:or :string :int]]]},
   :responses {200 [:map [:id :int] [:name :string] [:cat? :boolean] [:datetime [:or :string :int]]]}},
  :delete {:parameters {:path [:id :int]}, :responses {200 "OK"}}},
 :result nil,
 :path-params {:id "4"},
 :path "/test-model/4"}

So calling coerce! just returns nil, and the following test fails.

(is (= 4
         (-> (match-by-path-and-coerce! "/test-model/4")
             :parameters
             :id)))

Is it just breaking because of the lack of a handler function in the route map? Or am I missing something else? I've more or less copied the docs' examples verbatim here.

Those parameter Malli schemas don't seem valid?

[:id :int], should be [:map [:id :int]]?

Seems syntax error.