I'm having a hard time getting the nested behavior with controller start/stop behavior described here:
https://github.com/metosin/reitit/blob/master/doc/frontend/controllers.md#nested-controllers
It makes it sound like when you have a hierarchy like /a/b/c that even loading c that you should expect to see the a and b controllers invoked first.
Is there something special I have to do in order to make this work?
I'm not even convinced about the nested routes with "/" and then "/item/:id" -- doesn't this result in double leading slashes?
have you tried the frontend-controllers example? it works for me, and the controllers fire as expected
https://github.com/metosin/reitit/tree/master/examples/frontend-controllers
e.g. navigating to http://localhost:3449/#/items/1 , I see the following in my browser console: • start root-controller • start items controller • start item controller 1
@joel.kaasinen Yes, the example works for me, but it all seems quite fragile.
I don't think the explanations in the documentation are adequate, and it's not easy to debug into this stuff to understand what it is doing.
In terms of a data specification, I don't understand the entries in the tree where you have a path like /, which then has a child "" - this really seems like implementation details dominating the structure of the data.
I don't disagree
the fact that you can only have handlers in leaf nodes in the tree is subtle
Well, it is obviously very well regarded in the community. I just struggle with it every time I make a change and the docs say relatively little about it.
@joel.kaasinen Do you happen to have any insight how to debug this ?
no, not really, I haven't used reitit on the frontend that much. the controllers have always "just worked" for me.
@juhoteperi might be able to help you more
I'm editing it side-by-side with the frontend example you mentioned, and I'm tryin to make it as similar as possible, although the URL scheme is slightly different.
What is the difference between :compile function of middleware returning nil and {} ? What happens if both :compile and :wrap are defined in middleware?
my assumption would be that :compile overrides :wrap, and the docs & source support this
https://cljdoc.org/d/metosin/reitit/0.7.2/doc/ring/compiling-middleware
ok, so what’s the difference between returning nil and {} from compile?
re: nil vs {}, the docs describe using {}, but I'll have to dig into the source to figure out if nil is the same
if :compile overrrides :wrap then why is this namespace written like so:
(ns reitit.ring.middleware.parameters
(:require [ring.middleware.params :as params]))
(def parameters-middleware
"Middleware to parse urlencoded parameters from the query string and form
body (if the request is a url-encoded form). Adds the following keys to
the request map:
:query-params - a map of parameters from the query string
:form-params - a map of parameters from the body
:params - a merged map of all types of parameter"
{:name ::parameters
:compile (fn [{:keys [parameters]} _]
(if (and (some? (:form parameters)) (nil? (:body parameters)))
{:data {:swagger {:consumes ["application/x-www-form-urlencoded"]}}}
{}))
:wrap params/wrap-params})has both compile and wrap
right, I was actually confused myself
what happens is that the thing returned by :compile is turned into a middleware map using IntoMiddleware and then merged with the original middleware map
That’s what I thought
if :compile returns a function, that gets turned into {:wrap <function>} and thus overrides any :wrap in the original map
I see
but if :compile returns nil or {}, the original :wrap gets used
yeah that’s what I figued, but it’s nice to get a confirmation, thanks
no, wait, I still don't know what nil does, let me rephrase
nil will eliminate middleware from the chain
if :compile returns {}, the original :wrap gets used
yeah, that's what the code looks like
nil means skip this
because into-middleware for the whole map will return nil if :compile returns nil
the docs could be a lot better...
ah, it is mentioned in compiling_middleware.md:
However, in this case the compile function returns nil when that key is missing, which means the middleware will not be mounted, the spec will not be considered, and the compiler will not enforce this requirement as intended.