Fork me on GitHub
#reitit
<
2018-10-23
>
evangeline15:10:35

Hello, we're trying to use coercion to do backend validation with spec but kept having spec errors even when we're sending the correct data: [:spec "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req [:app/invites]), :type :map, :spec-tools.parse/key->spec {:app/invites :app/invites}, :spec-tools.parse/keys #{:app/invites}, :spec-tools.parse/keys-req #{:app/invites}})"][:problems [{:path [], :pred "map?", :val nil, :via [:app.web.invite/request], :in []}]][:type :reitit.coercion/request-coercion][:coercion :spec][:value nil][:in [:request :body-params]]

evangeline15:10:29

Spec seems to think that our body is nil and we initially thought one of our middlewares was causing this, but that doesn't seem like the case. FYI We are sending edn from the front end, with application/edn as our Content-Type, and our top-level handler is created using (rr/ring-handler (rr/router ...)). Our routes look something like this:

(rr/ring-handler
  (rr/router
    ["" {:coercion rspec/coercion
         :middleware [[wrap-protocol]
                      [wrap-defaults {:cookies true :params {:urlencoded true :keywordize true}}]]}
     ["/api" {:name "api routes"
              :middleware [[wrap-defaults defaults/api-defaults]
                           [wrap-cors]
                           [wrap-edn-params]]
              :options ok}
      ["" {:name "client api routes"
           :middleware [[wrap-session-auth]]}
       ["/invites" {:name "api/invites"
                    :parameters {:body :app.web.invite/request}
                    :responses {200 :app.web.invite/response
                                201 :app.web.invite/response}
                    :post invites}]]]]
    {:data {:middleware [rrc/coerce-exceptions-middleware
                         rrc/coerce-request-middleware
                         rrc/coerce-response-middleware]}})
  (-> (rr/create-default-handler)
      (wrap-defaults defaults/site-defaults)))

ikitommi15:10:31

@evangelinechengg the middleware stack is not easiest to debug. My 2cents are that your edn-middleware is pushing the parsed params into :edn-params, leaving the :body-params nil. You can add a debugging middleware between every mw to see how they transform the request, here's how: https://metosin.github.io/reitit/ring/transforming_middleware_chain.html

ikitommi15:10:54

I would recommend using Muuntaja for request & response formatting, here's a example: https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj

ikitommi16:10:44

it pushes all params (edn, json, transit) into :body-params.

evangeline16:10:30

that's what we suspected, we'll give Muuntaja a go and let you know how we get on 🙂