Fork me on GitHub
#reitit
<
2023-05-23
>
valerauko10:05:29

In a browser context, is it possible to achieve something like the trailing-slash handler on the server side? Eg have /new/ redirect to /new if /new/ is not defined

ikitommi12:05:35

isn’t this already impletented as a middleware? :thinking_face:

p-himik12:05:58

It is, as redirect-trailing-slash-handler. But it's for Ring.

ikitommi12:05:26

I read it wrong, question was for fe 🙈

valerauko13:05:54

I realized I won't need this, since the frontend router won't catch non-matching paths and so it'll just go to the server where i can use the trailing-slash handler

valerauko13:05:00

doing so i also realized that the trailing-slash handler does not work if the :inject-router option is false, apparently it depends on the router being in the request map

ikitommi12:05:18

hey, OpenAPI3-release will be delayed - goal is to have a new alpha within next 2 weeks with at least the following: • two-phase Schema compilation - https://github.com/metosin/reitit/pull/626 (merged) • Move OpenAPI 3 request coercions outside :parameters - https://github.com/metosin/reitit/issues/627

🚀 8
ikitommi12:05:34

the latter WILL BREAK syntax with early adopters of openapi3, but it will make things much better.

aaron5122:05:44

I want to override the HTTP method (get/put/post/patch/delete) in a hidden form element. I wrote a middleware that runs before the reitit router (i.e. before method-based routing). Is there a better way to do this in reitit or ring? Maybe this middleware already exists, or maybe there's an existing special parameter?

(defn wrap-override-method
  [handler]
  (fn [request]
    (let [method-param (get-in request [:params "_method"])]
      (handler (cond-> request
                 method-param (assoc :request-method
                                     (-> method-param
                                         lower-case
                                         keyword)))))))

(def app
  (-> (ring/ring-handler
       (ring/router
        [["/"
          {:get {:handler (constantly (response "This is a GET request"))}
           :post {:handler (constantly (response "This is a POST request"))}
           :put {:handler (constantly (response "This is a PUT request"))}}]]))
      wrap-override-method
      wrap-params
      wrap-multipart-params))

p-himik06:05:35

Not really an answer to your question, but I wouldn't use such an approach at all. At least to me it's a noticeable code smell that you have to override something as basic as HTTP method. Given that you seem to be in control of both the server and the client code, I'd settle on a single HTTP method (or a catch-all handler) that handles some known parameter in an explicit and more semantic way (`operation=create` or something like that). As to the answer that you've asked for - the way you did it seems to be reasonable, except that I would probably use an explicit case to avoid calling keyword on a presumably user-supplied data and passing that keyword to the rest of the system that's opaque to your app. And there doesn't seem to be any existing middleware that does something like that.

👍 2
jeroenvandijk07:06:10

Found this thread after looking for a solution for _method. Regardless of whether or not this is a good thing (I have my reasons), this approach is documented https://cljdoc.org/d/metosin/reitit/0.7.0-alpha5/doc/ring/restful-form-methods?q=_method#restful-form-methods

jeroenvandijk07:06:29

keyword in the above example could be replaced with a constant map generated with (into {} (map (juxt name identity)) reitit.ring/http-methods) . This would avoid the danger of interning arbitrary strings from the outside world

🙏 2
jeroenvandijk10:06:38

@U3JH0P5LJ Another major concern with your implementation is that you don’t check if the _method value was sent via the POST method. Your implementation exposes your users to XSS attacks. You should add a check like in the example above (= :post (:request-method request)). If you don’t do this then evil sites can add things like <img src=""> or <img src="http://yoursite.com/users/1/?_method=put&amp;user[role]=admin">`

🙏 2