How to do an upload using REST (Swagger) and Clojurescript (ajav
Hoping to help someone else that is also struggling with this.
I have used Luminus with Reagent to try this.
Luminus come with Swagger for REST API, it's a great tool because it gives you the possibility to try the API as soon as you have write it.
This is the code to write a REST end-point that accept a file in upload
Once you have added this. You should see in your Swagger ui (localhost:3000/swagger-ui) your new API, with the possibility to already send a file to try your logic (do-something-with)
Now let's go to the Clojurescript call (that is the hardest part, I lost an evening to figure out the right combination)
Hope this post will be useful.
Coming soon... How to style your input with a file using Bootstrap, Reagent and Clojurescript. How changing the label using a Reagent atom can give you some headache.
I have used Luminus with Reagent to try this.
Luminus come with Swagger for REST API, it's a great tool because it gives you the possibility to try the API as soon as you have write it.
This is the code to write a REST end-point that accept a file in upload
(ns your-clojure-ns
(:require [ring.util.http-response :refer :all]
[compojure.api.sweet :refer :all]
[schema.core :as s]
[ring.swagger.upload :as upload])
(defapi service-routes
{:swagger {:ui "/swagger-ui"
:spec "/swagger.json"
:data {:info {:version "1.0.0"
:title "Sample API"
:description "Sample Services"}}}}
(context "/your-context" []
:tags ["Your Context"]
(POST "/upload" []
:multipart-params [file :- upload/TempFileUpload]
:middleware [upload/wrap-multipart-params]
(ok (let [{:keys [filename tempfile]} file ]
(do-something-with tempfile)
{:success true}))))
You should already have the right imports in the file created by Luminus, the only one that you have to add is [ring.swagger.upload :as upload] that will give you the Middleware to use for your request.Once you have added this. You should see in your Swagger ui (localhost:3000/swagger-ui) your new API, with the possibility to already send a file to try your logic (do-something-with)
Now let's go to the Clojurescript call (that is the hardest part, I lost an evening to figure out the right combination)
(ns your-clojurescript-ns
(:require [ajax.core :refer [GET POST]]))
(defn upload-file [file]
(letfn [(handle-response-ok [] (js/alert "File Uploaded")
(handle-response-error []
(js/alert "There were problems during the upload"))]
(let [form-data (doto
(js/FormData.)
(.append "file" file))]
(POST "/your-context/upload"
{:body form-data
:response-format :json
:keywords? true
:handler handle-response-ok
:error-handler handle-response-error}))))
(.append "file" file) is very important, file is the same name you used in the clojure namespace as parameter, also you have to send the form-data as :body, if you try to send it as a :params (like is written around in internet) you will have an error.Hope this post will be useful.
Coming soon... How to style your input with a file using Bootstrap, Reagent and Clojurescript. How changing the label using a Reagent atom can give you some headache.
Awesome summary. Thank you!
ReplyDeleteQuite late reply :D but Thanks
Delete