reitit

plexus 2024-12-18T10:23:05.169459Z

I'm trying to figure out how to stop muuntaja from doing request parsing on a single route. It's a file upload route, I need access to the untouched body inputstream... I thought this might do it

["/foo" {:put {:muuntaja nil, :handler PUT-foo}}]
but so far that doesn't do much...

juhoteperi 2024-12-18T10:26:36.991629Z

Is the content-type one that Muuntaja handles?

opqdonut 2024-12-18T10:27:08.635939Z

could it be the coercion that's parsing the request? try :coercion nil

juhoteperi 2024-12-18T10:27:43.981589Z

If it is multipart, zip or image or such, I don't think Muuntaja should be touching the req body. I don't remember having to do much special tricks with Muuntaja when handling uploads.

plexus 2024-12-18T10:27:49.141309Z

tried that too @joel.kaasinen

juhoteperi 2024-12-18T10:27:53.352969Z

Though maybe I've added a multipart mw before muuntaja

opqdonut 2024-12-18T10:28:12.056449Z

yeah I have an upload here in my current project as well and no tricks needed

plexus 2024-12-18T10:28:24.446069Z

it's not multipart, it's an API call, just a plain request body

plexus 2024-12-18T10:28:53.745399Z

if I comment out the muuntaja request middleware I get what I want, so muuntaja is the culprit, not coercion

✅ 1
juhoteperi 2024-12-18T10:29:24.515019Z

Hhmhm. Not sure why removing the muuntaja instance doesn't work. Might depend on how the mw is applied to routes.

plexus 2024-12-18T10:29:57.408679Z

ok, so it's supposed to work this way. That's already good to know, then I can dig into why it's not 🙂

opqdonut 2024-12-18T10:30:00.967929Z

yeah it should get disabled by a nil muuntaja instance looking at the code

juhoteperi 2024-12-18T10:30:34.681769Z

If you can modify request :muuntaja/request property between format-negotiate-middleware and format-request-middleware that should also disable the request parsing for that request.

opqdonut 2024-12-18T10:30:39.398099Z

just checking: which muuntaja middleware? reitit.ring.middleware.muuntaja/format-middleware is the one I'm looking at

👍 1
plexus 2024-12-18T10:30:54.124639Z

I tried to dig through the code but the route compilation I find confusing...

juhoteperi 2024-12-18T10:31:04.508019Z

https://github.com/metosin/reitit/blob/master/modules/reitit-middleware/src/reitit/ring/middleware/muuntaja.clj#L72 Yeah this should correctly apply the mw to the route only if route data has muuntaja instance

juhoteperi 2024-12-18T10:31:08.145009Z

but hmm

juhoteperi 2024-12-18T10:31:20.034969Z

try moving :muuntaja property outside of :put data

juhoteperi 2024-12-18T10:32:03.024019Z

http methods are special case... routing happens with only the path information, so maybe mw are applied before the method is checked

opqdonut 2024-12-18T10:32:07.157829Z

the mw is looking for muuntaja on the same level as parameters, so I doubt that'll help

juhoteperi 2024-12-18T10:32:15.616349Z

ah true

opqdonut 2024-12-18T10:33:19.453579Z

I wonder if there's a nice way to print out the compiled routes...

plexus 2024-12-18T10:33:57.712029Z

tried moving it up but no luck

opqdonut 2024-12-18T10:35:07.252679Z

route-data is merged using meta-merge... does the nil value need a ^:replace?

opqdonut 2024-12-18T10:35:21.611109Z

you could try using r/match-by-path to see if the match contains a muuntaja instance

💯 1
plexus 2024-12-18T10:36:35.340429Z

great suggestion! I don't think nil can take metadata.

opqdonut 2024-12-18T10:36:57.315389Z

yeah just realised that as well...

opqdonut 2024-12-18T10:37:01.953259Z

and yeah, meta-merge ignores nils

juhoteperi 2024-12-18T10:37:12.342669Z

false might work

opqdonut 2024-12-18T10:37:20.960919Z

user=> (require '[meta-merge.core :refer [meta-merge]])
nil
user=> (meta-merge {:a 1} {:a nil})
{:a 1}
user=> (meta-merge {:a nil} {:a 1})
{:a 1}

juhoteperi 2024-12-18T10:37:21.794529Z

but didn't we have our own meta-merge like merge for reitit 😄

opqdonut 2024-12-18T10:37:34.978489Z

let me check, I thought we use the official one...

juhoteperi 2024-12-18T10:38:10.617589Z

yeah it is the regular meta-merge

juhoteperi 2024-12-18T10:39:07.872669Z

https://github.com/metosin/reitit/issues/243

👀 1
opqdonut 2024-12-18T10:39:12.295609Z

user=> (require '[reitit.impl :refer [meta-merge]])
nil
user=> (meta-merge {:a 1} {:a nil} {})
{:a 1}
user=> (meta-merge {:a nil} {:a 1} {})
{:a 1}
user=> (meta-merge {:a 1} {:a false} {})
{:a false}
(extra param is opts)

juhoteperi 2024-12-18T10:40:25.201169Z

Oh right the reitit meta-merge opts also allows you to replace meta-merge impl...

plexus 2024-12-18T10:40:42.176979Z

YES false does the trick

plexus 2024-12-18T10:40:49.766119Z

THANK YOU 🙏

juhoteperi 2024-12-18T10:41:05.566659Z

And update-paths option is to handle Malli schema merge IIRC

plexus 2024-12-18T10:41:08.568899Z

ugh such an annoying meta-merge sharp edge

😿 1
opqdonut 2024-12-18T10:41:14.511399Z

pro tip: use :muuntaja false in route data to disable muuntaja (or anything else) for a single route. :muuntaja nil doesn't work

opqdonut 2024-12-18T10:43:50.712929Z

I wonder... should we document this better? Here? https://github.com/metosin/reitit/blob/master/doc/basics/route_data.md

plexus 2024-12-18T16:19:56.905969Z

it wouldn't hurt to have an example in there of how to override something like muuntaja, it's not always obvious where the keys should go