Fork me on GitHub

@david.russell if you don’t need dynamic routers, just use data. Something like:

(defn generic-routes [args]
  ["/baz" {:get (handler-to-do-something-with args)}])

(defn foo-routes [args]
    ["/foo" (constantly {:status 200, :body "foo"})]
    (generic-routes args)]])

(defn bar-routes [args]
    ["/bar" (constantly {:status 200, :body "bar"})]
    (generic-routes args)]])

(defn all-routes [args]
  [(foo-routes args)
   (bar-routes args)])


reitit automatically flattens sequential routes, so you can return partial routes either as singular:

(defn routes [_] ["/ping" handle-ping])
or as list of routes:
(defn routes [_] [["/ping" handle-ping]])
or even:
(defn routes [_] [[[[["/ping" handle-ping]]]]])
all work the same.


some smarter people might say, but makes programming with routes much easier.


also, nils are removed automatically, so you can:

 (if (dev-mode) ["/remove-db" remove-db-handler])]


everything is done at router creation time, so the end-result is an optimized route tree.


hope this helps.

Dave Russell08:11:16

It definitely does -- I just tested the data-based approach you suggest and it works perfectly. I'm not sure why I reached first for a macro 🙂 The nil and flattening is also super helpful because I was previously wrapping routes so that a single tree was returned, but a list of routes is more ergonomic. Thanks very much!!


Hey! Quick barrage of Reitit questions. 1. Reading Reitit's Cljdoc on coercion[1], I was surprised that Malli was not mentioned. Yet, Malli seems to come as a dependency to Reitit. On the other hand, the ring-swagger example[2] uses Malli. I assume there's plans to make Reitit and Malli play nice together; and that docs for using Malli for reitit coercion will be added as Malli approaches a stable release? 2. I want request coercion. I like Reitit and Malli's data-driven approach. Are there reasons to pick Plumatic Schema, Sclojure.spec or Data-specs over Malli? 3. Is the ring-swagger example a good way to get started with Reitit and Malli? [1]: [2]:


The ring-swagger example might not be using malli after all. With an invalid JSON request, I'm getting a spec tools error message:

"(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:spec$8818/x :spec$8818/y]), :type :map, :leaf? false})"


@teodorlu please PR Malli for the docs! Just forgot those.


@U055NJ5CC PR: I wasn't able to test with cljdoc locally, but the change is quite simple.


currently porting a schema-based project to use malli, fixing the rough edges on the process. E.g. the date-support is not as good yet and there is a design bug in accumulating schemas in reitit, most visible with malli:

👍 3

Thanks for the correction (ring-malli-swagger) & the link to the issue. It was useful to see a smaller example (issue). I'm not promising a PR for Malli coercion docs, but it would be a good excercise to build a proper understanding :thumbsup:


Why does this fail?

(def routes
   {:get {:handler    ok
          :middleware [#(wrap-resource % "public")]}}])

(def router
  (ring/router routes))

(def app
  (ring/ring-handler router))

(jetty/run-jetty (wrap-reload #'app) {:port  3000 :join? false}))
ok is (constantly {:status 200 :body "ok"}) - ring is reitit.ring There is an index.html in public, it's served alright when I just wrap the ok handler directly in wrap-resource and put it in jetty. This way I get HTTP ERROR 500 java.lang.NullPointerException: Response map is nil


@d.eltzner reitit is route-first, you are only mapping an exact "/" match. You should either 1) use a wildcard route 2) use the ring-router default-handler argument or 3) add the middleware into ring/ring-handler with :middleware option. 2 is the best imo, docs should cover how to do that.