Fork me on GitHub
#reitit
<
2020-08-18
>
nando13:08:05

So, I've switched to using reitit in the app I'm using to learn Clojure, and have been pouring through the examples on github and the documentation to work out how to apply middleware. The buddy-auth example seems to be the best I've found so far. The documentation on applying the default middleware https://cljdoc.org/d/metosin/reitit/0.5.5/doc/ring/default-middleware doesn't explicitly explain how to do it, and my naive attempts have failed so far. Any pointers how to do it? TIA

dharrigan13:08:10

Where are you stuck?

timo14:08:00

@nando https://github.com/metosin/reitit/issues/185 this issue tracks this and it is indeed good to have a look at the link because there you can copy stuff if you want to :thumbsup:

GGfpc15:08:38

Hi! I have a somewhat broad question. I don't really do frontend and I'm starting now. On my backend I use compojure and ring for my REST API, and I need to implement page where the user can be redirected to for oauth purposes on the frontend. It seems like reitit is the right tool for this, but at the same time I can't tell the difference between reitit and compojure. Is reitit overkill for a simple redirect (where I need access to query params)?

nando22:08:45

As I am learning reitit at the moment, I can only say that you can use reitit in a very simple manner. As a ring router, it is as simple as compojure - in fact I would say more simple now that I am starting to understand how middleware is applied.

nando18:08:16

@dharrigan I'm trying to put together a Middleware Overview in my head. As it stands, the documentation and examples present fragments. I see 3 points where middleware can be defined/included. 1) a vector of names and or keywords as the value attached to the keyword :middleware

(:require
...
[reitit.ring.middleware.parameters :as parameters]
)

(def app
  (ring/ring-handler
   (ring/router
    [["/" {:get handler/home}]
     ["/dump" {:get handle-dump
               :middleware [parameters]}]
     ]
    )
   (ring/redirect-trailing-slash-handler {:method :strip})
   (ring/create-default-handler)
   
   ))

nando18:08:15

The above naive approach doesn't work. I get a "Unable to resolve symbol: parameters in this context". So I'm working on understanding where / how the values in this vector or defined.

nando18:08:45

2) I see there is an approach to apply middleware to all the routes in a router using a nested map with the :data keyword whose value is a map with the :middleware keyword. Using the buddy-auth example and the following sentence in the docs on the Default Middleware page: reitit.ring.middleware.parameters/parameters-middleware to capture query- and form-params. Wraps `ring.middleware.params/wrap-params` I got this to successfully compile and work just now:

(def app
  (ring/ring-handler
   (ring/router
    [["/" {:get handler/home}]
     ["/dump" {:get handle-dump}]
     ]
    {:data {:middleware [parameters/parameters-middleware]}}
    )
   (ring/redirect-trailing-slash-handler {:method :strip})
   (ring/create-default-handler)
   
   ))
Ok, so that's progress, but how would I apply a middleware declared in the :require vector to a single route as in 1) above.

nando18:08:07

3) I see in the docs there is a Middleware Registry. Yesterday, I was quite confused by the examples. Today, I think there might be a typo in the Works as expected example, which has a :bonus10 middleware in the code, when I suspect it should read :bonus 10 ... but wait, maybe I'm still confused. I see :bonus10 IS registered in the middleware registry, so it's not a typo. A less convoluted example might be more clear for a bonehead like me. The fact that the example adds bonuses within a request (huh???) also threw me off. Today I assume it is contrived to demonstrate the point that one middleware can refer to another in the registry?

{::middleware/registry {:bonus wrap-bonus
                        :bonus10 [:bonus 10]}}

nando19:08:03

Is there a clear benefit to adding middleware to the registry beyond what is stated at the bottom of the documentation in the When to use the registry section? As I see it, the registry simply assigns a keyword to a function, right?

dharrigan19:08:47

I don't see why #1 wouldn't work. I.e., in this example there is a basic auth middleware injected into the route for /basic-auth and similarly for /token-auth

dharrigan19:08:01

I've mostly used #2 atm 🙂

dharrigan19:08:25

I think with #1, wouldn't you have to do parameters/parameters-middleware?

dharrigan19:08:15

For example, in my middleware, which admittingly uses the :data {.... approach, I have:

dharrigan19:08:28

{:validate rs/validate
    :data {:coercion rcm/coercion
           :muuntaja m/instance
           :middleware [swagger/swagger-feature
                        muuntaja/format-middleware
                        (exceptions/exception-middleware app-config)
                        parameters/parameters-middleware
                        coercion/coerce-exceptions-middleware
                        coercion/coerce-request-middleware
                        coercion/coerce-response-middleware]}}))

dharrigan19:08:39

notice that I use parameters/parameters-middleware

dharrigan19:08:06

I have my own exceptions middleware which hooks into sentry... 🙂

nando19:08:40

@https://app.slack.com/team/U11EL3P9U I just thought of trying the fully qualified name parameters/parameters-middleware for #1 ... will do in a few minutes.

nando19:08:48

Yesterday and today have been a process of hunting around and piecing together the story from a variety of different sources in the documentation and examples.

dharrigan19:08:35

It can be an adventure, I admit 🙂

haywood20:08:36

anyone have trouble getting the backward / forward buttons working with reitit frontend?

haywood20:08:27

when hitting the back button, my on-navigate function is called correctly, but the match is the current route

nando21:08:33

@dharrigan So reporting back, I've tried several things in my #1 case and found they work.

["/dump" {:get handle-dump
               :middleware [parameters/parameters-middleware]}]
The above now works as expected. I have the form, path, query and root params added to the request. So I added a [ring.middleware.params :as params] to the :require block and found that the following also works:
["/dump" {:get handle-dump
               :middleware [params/wrap-params]}]
So I'm seeing how to pull middleware in directly from ring or any other namespace and apply it either individually to a route or collectively to the whole router.