Fork me on GitHub

@benny you should declare a :coercion , e.g. :coercion reitit.coercion.spec/coercion into route data. It is used to transform the :parameters and :responses into JSON/Swagger Schema for api-docs.


thanks @ikitommi somehow reitit.coercion.spec/coercion is not being found when i have the uber reference, am i supposed to have something else pulled in for it to be recognized?


what is an uber reference? you need reitit-spec module at least, or reitit , which contains all other modules


i just meant the main reference to reitit (no specific references)


@amarjeet do you handle the middleware chain as list/seq at some point? all declarations should be in vectors.


Hi @ikitommi, I tested with a small sample:

(ns cljservice.http.temp
  (:require [ring.middleware.json :refer [wrap-json-params wrap-json-response]]
            [ring.middleware.keyword-params :refer [wrap-keyword-params]]
            [reitit.ring :as ring]
            [aleph.http :as http]))

(defn get-handler [req]
  {:status 200
   :headers {"Content-Type" "application/json"}
   :body {:Response "Hello http-get world!"}})

(defn my-middleware [handler v]
  (fn [req]
    (let [response (handler req)]
      (assoc-in response [:body "middleware-val"] v))))

(def router
   [["/" {:middleware [[wrap-json-response] [my-middleware 3] [my-middleware 2] [wrap-json-params] [wrap-keyword-params]]
          :get get-handler}]]))

(def app (ring/ring-handler

(defn start-http-server []
  (http/start-server app {:port 3000}))
Now, if I make a get request, the middleware-val has value 3, not 2.


Middlewares are in vec in this case.


middleware is a 2-way chain: here it’s json-response -> 3 -> 2 -> json-params -> wrap-keywords. For request, it’s processes in that order. For response it’s reverse (as it’s just a higher order function chain).


you are assoccing to response in the response pipeline.


there is a middleware chain diff printer which shows the order of things and the effects of each middleware, see examples.


hope this helps


Aah, my bad - I realize now.


Thanks 🙂


You’re Welcome


@rgm If I understood correctly, you want to filter out routes that don’t have a :handler / :name etc defined. there is a guide for composing routers here: - basically: create a router with expanded things, pull out the routes (they are now flattened, filter the data and create a new router.

🙏 3

Oh, that’s great! Thank you… I really like the idea that a router can be treated a coll of routes and all I need is good old (remove nil? ,,,) against the route data at start-up time. Right now I’m just gapping out the ignore-anchor-request? at run-time.


I’ll read the composing routers page more closely … I’ve scanned it a couple of times but I’ve had that thing going on where I just needed a bit of help to recognize that I have a problem that it solves.


you might be able to do that within a router using the route compiler, but the solution might be more complex.


the route tree merging and flattening utils are in reitit.impl , not part of the public api.


This is one of the sweet-spots of data-oriented route tables: you can add data like :dispatcher :nio and collect those routes into separate router, to be run nio the server NIO pool. Also tag routes with cluster info like :service/group "abc", and do multiple server provisioning with partial route tables. Monolithic Design, with micro deployments.

Eyal H09:09:52

Hey, I'm using the reitit.coercion.spec/coercion in reitit to validate the route, path and body of the request. I'm doing some benchmarking with non-valid requests (body params) and I noticed that the CPU is working very hard (4 CPU machine - 100% utilization when I fire 6000 req/sec). When the request is valid, CPU utilization is quite low (30-40%). Any idea what's causing the CPU to reach 100%?

Eyal H09:09:06

{:exception pretty/exception
                 :data      {:coercion   rcs/coercion
                             :muuntaja   muuntaja/instance
                             :middleware [swagger/swagger-feature
Middlware configuration

Eyal H09:09:16

The validation I'm doing is a simple one - validating strings

Eyal H09:09:59

Snapshot of falmegraph of one thread


@eyaldocs could you run the same benchmark with malli coercion? On my tests, it's 1-3 orders of magnitude faster than spec


on a side-note: doing a spike on running the json->malli transformations within Jackson, removes one step (doing garbage) in the pipeline, should make things faster.

Eyal H10:09:40

Thanks, @ikitommi I"ll give malli a try. Can you please elaborate on your side note, what exactly should I do


different :coercion , different way to describe the parameters and reaponses

Eyal H10:09:02

Yes, thanks, I understood this part

Eyal H10:09:22

I was talking about the second part of your answer


not implemented and don’t know how to integrate that in yet. I think we need to add a new protocols for muuntaja & reitit-coercion to negotiate that the coercion happens within json-decoding and the separate coercion is not needed. At code level, would like:

(require '[jsonista.malli :as jm])
(require '[malli.core :as m])

(def decode
  (m/decoder [:map [:x keyword?]] (jm/json-transformer {:strip-extra-keys true})))

(decode "{\"x\": \"kikka\", \"y\": 123}")
; => {:x :kikka}


basically what the statically typed langs have had already for ages.

👍 3
Michaël Salihi13:09:57

Hi Reitit luvers! I want to share this GIT repository that might be useful. This is the useful usermanager example of @seancorfield ( but for which for learning purposes, I started again from scratch by replacing the Compojure librarie by Reitit and Component by Integrant : Cheers!


@admin055 thanks! could you do a PR and add it to reitit README so it’s found? there are some links there already.

Michaël Salihi13:09:04

Yes, for sure @ikitommi. Which section? "More examples" part?


sure, or a new section of external resources, or whatever feels good

Michaël Salihi14:09:14

OK, another section is what I think is best since "More examples" are examples from the Reitit repo only. :thumbsup:


Merged, thanks!

Michaël Salihi16:09:11

You're welcolme, thx to you!


I should add my one, which is a simple startrek one + frontend/backend reitit with juxt clip


I'll do a PR soon

👍 6

PR now available 🙂

Felipe Marques15:09:58

Hello! I'm having problems with using Reitit in the Front-end. The coercion of path params works in dev but when I compile and serve the JS, it doesn't. Did anyone have a similar problem?

Felipe Marques14:09:53

The problem disappears when I change the optmization from :simple to :advanced