reitit

https://cljdoc.org/d/metosin/reitit/ https://github.com/metosin/reitit/
nando 2020-08-18T13:44:05.069600Z

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

dharrigan 2020-08-18T13:53:10.069900Z

Where are you stuck?

timo 2020-08-18T14:51:00.070900Z

@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:

GGfpc 2020-08-18T15:42:38.073700Z

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)?

nando 2020-08-18T18:15:16.080200Z

@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)
   
   ))

nando 2020-08-18T18:20:15.081800Z

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.

nando 2020-08-18T18:37:45.088200Z

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.

nando 2020-08-18T18:57:07.094800Z

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]}}

nando 2020-08-18T19:09:03.098100Z

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?

dharrigan 2020-08-18T19:43:47.099200Z

I don't see why #1 wouldn't work. I.e., in this example <https://github.com/metosin/reitit/blob/master/examples/buddy-auth/src/example/server.clj> there is a basic auth middleware injected into the route for /basic-auth and similarly for /token-auth

dharrigan 2020-08-18T19:45:01.099700Z

I've mostly used #2 atm 🙂

dharrigan 2020-08-18T19:46:25.100200Z

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

dharrigan 2020-08-18T19:48:15.100700Z

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

dharrigan 2020-08-18T19:48:28.100900Z

{: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]}}))

dharrigan 2020-08-18T19:48:39.101200Z

notice that I use parameters/parameters-middleware

dharrigan 2020-08-18T19:49:06.101700Z

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

nando 2020-08-18T19:51:40.102700Z

@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.

dharrigan 2020-08-18T19:51:53.102900Z

np 🙂

nando 2020-08-18T19:53:48.104Z

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.

dharrigan 2020-08-18T19:54:35.104300Z

It can be an adventure, I admit 🙂

haywood 2020-08-18T20:12:36.106500Z

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

haywood 2020-08-18T20:22:27.107Z

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

haywood 2020-08-18T20:28:31.107400Z

I’m not sure how it would work since we’re not tracking previous states? https://github.com/metosin/reitit/blob/577447dc2321d36d5a4f439b3d6486e8e5b3e004/modules/reitit-frontend/src/reitit/frontend/history.cljs#L94-L133

nando 2020-08-18T21:56:33.108500Z

@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.

nando 2020-08-18T22:10:45.108800Z

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.