Fork me on GitHub
#reitit
<
2021-09-11
>
Oliver Marks12:09:45

Hi, I am after some advise I am using reitit and malli, I have a spec which takes a user I send some json over the wire is there a way I can inject a key value of a user server side looking up the using then injecting the user id into the json body so my spec passes ?

Oliver Marks12:09:38

I could create 2 specs one with the usesr id and one with out using on in the request body validation then insert the user id and run the spec again with the added user spec, it would be nice if I could do this in one, my other options could be disable the specs and do them manually but I figure there might be other options ?

ikitommi13:09:20

@olymk2 you need to inject enrichment logic between the forrmat-middleware and coercion-middleware. If the logic for request enrichment varies per endpoint, you could create a mw, that reads an enrichment function from route data. The mw-chain would be [... format-mw my-enricher-mw coercion-mw ...] and the route data could be something like:

{:post 
  {:parameters ...
   :before (fn [request] ...)
   :handler (fn [request] ...)}}

ikitommi13:09:01

... where the my-enricher-mw reads the :before and runs it. Hope this helps.

Oliver Marks16:09:18

okay thats kind of what i wass hoping for so in the example above you have a middleware chain which I guess is at route level, currently I have global middleware which is almost straight from the docs

(defonce malli-coercsion
  (reitit.coercion.malli/create
   {:transformers {:body {:default reitit.coercion.malli/default-transformer-provider
                          :formats {"application/json" reitit.coercion.malli/json-transformer-provider
                                    ;; transit-json should not be needed keywrods are posted as text currently
                                    ;; this quickly fixes it
                                    "application/transit+json" reitit.coercion.malli/json-transformer-provider}}
                   :string {:default reitit.coercion.malli/string-transformer-provider}
                   :response {:default reitit.coercion.malli/default-transformer-provider}}
    :error-keys #{:type :coercion :in :schema :value :errors :humanized}
    :compile malli.util/closed-schema
    :validate true
    :enabled true
    :strip-extra-keys true
    :default-values true
    :options nil}))

(def app-ring-middleware
  {:validate rrs/validate
   :exception pretty/exception
   :data {:coercion malli-coercsion 
          :muuntaja new-muuntaja-instance 
          :middleware feature-middleware}})
so would I need to make this local instead or am i not understanding where to inject my middleware, I also need to look up the :before key as I have not come accross that previously

Oliver Marks19:09:03

@ikitommi Had time to process I think I get it now although realize I might need the extra malli schema as the api will show the user attribute as required even when injected which you would not really want unless you can exclude certain value from swagger some how