feat: openapi3 multipart support for spec

This commit is contained in:
Joel Kaasinen 2023-03-15 10:22:26 +02:00
parent 8bf4b5c6a6
commit f322597c04
3 changed files with 47 additions and 3 deletions

View file

@ -19,13 +19,17 @@
"Spec for file param created by ring.middleware.multipart-params.temp-file store."
(st/spec
{:spec (s/keys :req-un [::filename ::content-type ::tempfile ::size])
:swagger/type "file"}))
:swagger/type "file"
:openapi {:type "string"
:format "binary"}}))
(def bytes-part
"Spec for file param created by ring.middleware.multipart-params.byte-array store."
(st/spec
{:spec (s/keys :req-un [::filename ::content-type ::bytes])
:swagger/type "file"}))
:swagger/type "file"
:openapi {:type "string"
:format "binary"}}))
(defn- coerced-request [request coercers]
(if-let [coerced (if coercers (coercion/coerce-request coercers request))]

View file

@ -108,7 +108,7 @@
(update $ :schema #(coercion/-compile-model this % nil))
$))]))})))
:openapi (merge
(when (seq (dissoc parameters :body :request))
(when (seq (dissoc parameters :body :request :multipart))
(openapi/openapi-spec {::openapi/parameters
(into (empty parameters)
(for [[k v] (dissoc parameters :body :request)]
@ -124,6 +124,12 @@
(into {}
(for [[format model] (:content (:request parameters))]
[format (coercion/-compile-model this model nil)])))})})
(when (:multipart parameters)
{:requestBody
(openapi/openapi-spec
{::openapi/content
{"multipart/form-data"
(coercion/-compile-model this (:multipart parameters) nil)}})})
(when responses
{:responses
(into

View file

@ -8,6 +8,7 @@
[reitit.coercion.malli :as malli]
[reitit.coercion.schema :as schema]
[reitit.coercion.spec :as spec]
[reitit.http.interceptors.multipart]
[reitit.openapi :as openapi]
[reitit.ring :as ring]
[reitit.ring.spec]
@ -429,6 +430,39 @@
(testing "spec is valid"
(is (nil? (validate spec))))))))
(deftest multipart-test
(doseq [[coercion file-schema]
[#_[#'malli/coercion (fn [nom] [:map [nom :string]])]
#_[#'schema/coercion (fn [nom] {nom s/Str})]
[#'spec/coercion reitit.http.interceptors.multipart/bytes-part]]]
(testing coercion
(let [app (ring/ring-handler
(ring/router
[["/upload"
{:post {:decription "upload"
:coercion @coercion
:parameters {:multipart {:file file-schema}}
:handler identity}}]
["/openapi.json"
{:get {:handler (openapi/create-openapi-handler)
:openapi {:info {:title "" :version "0.0.1"}}
:no-doc true}}]]
{:data {:middleware [openapi/openapi-feature]}}))
spec (-> {:request-method :get
:uri "/openapi.json"}
app
:body)]
(testing "multipart body"
(is (= {:requestBody {:content {"multipart/form-data" {:schema {:type "object"
:properties {"file" {:type "string"
:format "binary"}}
:required ["file"]}}}}}
(-> spec
(get-in [:paths "/upload" :post])
#_normalize))))
(testing "spec is valid"
(is (nil? (validate spec))))))))
(deftest per-content-type-test
(doseq [[coercion ->schema]
[[#'malli/coercion (fn [nom] [:map [nom :string]])]