Fork me on GitHub
#reitit
<
2018-04-06
>
conan14:04:44

Me again. I've made lots of progress and moved all my routes over to reitit, which was really straightforward! I can't get wrap-resource middleware working though, static things will only be served when I wrap the handler provided by rr/ring-handler. So this works:

(wrap-resource 
  (rr/ring-handler 
    (rr/router ["" 
                ["/" {:handler index-page}]
                ["/banana" {:handler peel}]])) 
  "public")
But this does not:
(rr/ring-handler
  (rr/router ["" {:middleware [[wrap-resource "public"]]}
              ["/" {:handler index-page}]
              ["/banana" {:handler peel}]])) 
  
What am I misunderstanding?

ikitommi16:04:36

@conan wrap-resource is special middleware that serves routes behind the scens. Reitit is a route-first architecture: match first, then apply all the middleware for the matched route. Your second example doesn’t work because the route tree handles only exact matches “/” and “/banana” and thus, doesn’t match.

ikitommi16:04:18

you can add a "/*" path to match anything and serve static resources from that.

ikitommi16:04:28

but there is a caveat: having both "/" and "/*" will cause a route conflict.

ikitommi16:04:50

so, you have the following options:

ikitommi16:04:50

1) wrap the wrap-resouces over the router (your first example) => this is not good as for all routes, the mw check if there is a static file present. This is extra IO and slows the app down. 2) add a wildcard route and serve static resources from there: ["/*" {:middleware [[wrap-resource "public"]]}] + disable the route conflict resolution (with :conflicts router option) 3) wrap the default handler with the ring default handler

conan16:04:56

thanks. ok yes i see that i don't want to wrap everything in the static check. i'll look into the conflict resolution. i don't quite understand what you mean by 3)?

ikitommi16:04:24

(ring/ring-handler
  (ring/router
    [["/" {:handler index-page}]
     ["/banana" {:handler peel}]])
  (wrap-resource
    (ring/create-default-handler)
    "public"))

ikitommi16:04:56

the ring-handler takes optional second parameter which is the default-handler, it’s just a ring-handler

ikitommi16:04:29

(ring/create-default-handler) creates a default-handler with good’ish defaults.

ikitommi16:04:31

in 3, it first checks the resource, then serves the 404-406 based on the request, see https://metosin.github.io/reitit/ring/ring.html#default-handler

conan16:04:17

oh and of course there's no wildcard route in here so it's ok, that's a great idea!

ikitommi16:04:25

aside other things, I’m rewriting Immutant core for better perf, plan is to ship a fully async resource handler, as an option to the ring resource-middleware.

ikitommi16:04:19

would look the same but would be much faster.

ikitommi16:04:13

not sure if that will be merged back to Immutant, but nice to study how the NIO-stuff works.