yada 2019-06-08

How do I save a file uploaded via POST and multipart/form-data? For example, the following resource reports an error:

(resource
            {:methods {:post {:consumes  "multipart/form-data"
                              :parameters {:form {:photo java.io.File}}
                              :response
                              (fn [ctx]
                                (let [photo (-> ctx :parameters :form :photo)]
                                  (->> "photo.jpg"
                                    (io/file "resources" "passengers")
                                    (io/copy photo))))}}})
The error is:
Bad form fields

{:status 400,
 :error
 {:photo (not (instance? java.io.File a-yada.multipart.DefaultPart))}}
io is an alias for ; I tried a similar implementation with an io/writer inside a with-open clause but got No matching method found: write for class java.io.BufferedWriter errors, so tried io/copy instead to see what that would show up. How do I use the multipart data? I see there’s a process-request-body method implementation for multi-part bodies in yada.multipart but I’ve no idea how to invoke it (or why isn’t it being invoked on my behalf by yada when it sees the content type?)

If I follow an example I found and implement a :consumer entry on the resource, the file of the correct size is created, but it’s not parseable as an image (I’m uploading a jpg and giving it that file extension):

:consumer (fn [ctx _ body-stream]
                                          (let [file (io/file "resources" "passengers" "photo.jpg"))]
                                            (yada.consume/save-to-file ctx body-stream file)))

Setting the content-type to application/octet-stream instead works fine, but it’d be great to know what I was doing wrong with the mulitpart/form-data content-type payload (if only so I can POST forms that include photos or other binary payloads in the future)