This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-05
Channels
- # announcements (2)
- # babashka (23)
- # beginners (67)
- # biff (4)
- # calva (19)
- # cider (6)
- # clj-kondo (40)
- # clj-yaml (14)
- # clojure (3)
- # clojure-austin (13)
- # clojure-europe (18)
- # clojure-nl (1)
- # clojure-norway (26)
- # clojure-uk (5)
- # clojurescript (42)
- # datascript (2)
- # datomic (6)
- # emacs (32)
- # graalvm (8)
- # humbleui (12)
- # hyperfiddle (13)
- # jobs (5)
- # lambdaisland (1)
- # lsp (18)
- # malli (15)
- # off-topic (20)
- # overtone (1)
- # pathom (5)
- # pedestal (15)
- # portal (3)
- # reitit (13)
- # releases (1)
- # remote-jobs (1)
- # yamlscript (4)
Hi, what would be the best way to get Reitit to check that a URL path parameter is an integer during routing? eg. /customer/:id
should match /customer/99
but /customer/abc
shouldn't and should 404. I'm coming from Python/Django which has rexexp-type patterns and coercion built into the routing, eg. path('/customer/<int:id>/', handler)
. I've set up spec coercion with Reitit, but the route will match any :id
value and return a 400 with the spec JSON, rather than failing to match.
you should be able to capture the coercion error and handle it yourself to return a 404… very manual process but doable
thanks @U0479UCF48H
Right, I think I'm starting to get my head around reitit a little. So by design, both (r/match-by-path router "/customer/99")
and (r/match-by-path router "/customer/abc")
will return a match for "/customer/:id"
- there's no way at the router level to match if the parameter looks like an integer? That concern is left to the middleware or handler?
This is my first naive pass at a middleware to convert these spec coercion errors into a 404:
(def wrap-spec-coercion-error
{:name ::wrap-spec-coercion-error
:wrap (fn [handler]
(fn [request]
(let [response (handler request)]
(if (get-in response [:body :problems])
{:status 404 :body "Path invalid" :headers {"Content-Type" "text/html"}}
response))))})
(This is a server-side HTML app I'm working on, rather than an API, so I'm hoping to return a friendly 404 page rather than the spec error JSON)
I need the raw submitted body of the POST request, but I don’t know how can I do that? I did something like this:
{:post {:parameters {:body any?}
:response {200 {:body any?}}
:handler payment/webhook}}
But it parses the body and I cannot get the raw body in any way. I’ve tried (ring.util.request/body-string request)
but that returns an empty String
, I guess because the body was already parsedif I remove the :parameters
then it does not parse the params but the body is still not available
I've done this by creating a new wrap middleware, and then wrapping my route(s) with that middleware. My use-case was validating Stripe webhook calls, where I need the raw body to compute its signature and compare it against the signature in the request.
(defn wrap-raw-body [handler]
(fn [request]
(let [buffered-body (slurp (:body request))
body-stream (io/input-stream (.getBytes buffered-body))
parsed-body (json/parse-string buffered-body keyword)]
(handler (assoc request :body body-stream :raw-body buffered-body
:body-params parsed-body)))))
Initial discussion was in the context of Pedestal: https://clojurians.slack.com/archives/C0K65B20P/p1696055080976369
This is exactly the reason I need it. Thank you! I am sure it can be done with a middleware or an interceptor, but I thought it is possible somehow without that.
Then I guess I’ll need to create an interceptor that can be enabled on certain endpoints to return the raw body.