@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"
["/foo" (constantly {:status 200, :body "foo"})]
(generic-routes args)]])
(defn bar-routes [args]
["/bar"
["/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 https://stuartsierra.com/2015/06/10/clojure-donts-heisenparameter, but makes programming with routes much easier.
also, nil
s are removed automatically, so you can:
["/admin"
(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.
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]: https://cljdoc.org/d/metosin/reitit/0.5.10/doc/coercion [2]: https://github.com/metosin/reitit/blob/master/examples/ring-swagger/src/example/server.clj
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.
https://github.com/metosin/reitit/tree/master/examples/ring-malli-swagger is the malli-variant
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: https://github.com/metosin/reitit/issues/422
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:
@ikitommi PR: https://github.com/metosin/reitit/pull/448/files I wasn't able to test with cljdoc locally, but the change is quite simple.
thanks!
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.