mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
feat: openapi3 multipart support for spec
This commit is contained in:
parent
8bf4b5c6a6
commit
f322597c04
3 changed files with 47 additions and 3 deletions
|
|
@ -19,13 +19,17 @@
|
||||||
"Spec for file param created by ring.middleware.multipart-params.temp-file store."
|
"Spec for file param created by ring.middleware.multipart-params.temp-file store."
|
||||||
(st/spec
|
(st/spec
|
||||||
{:spec (s/keys :req-un [::filename ::content-type ::tempfile ::size])
|
{:spec (s/keys :req-un [::filename ::content-type ::tempfile ::size])
|
||||||
:swagger/type "file"}))
|
:swagger/type "file"
|
||||||
|
:openapi {:type "string"
|
||||||
|
:format "binary"}}))
|
||||||
|
|
||||||
(def bytes-part
|
(def bytes-part
|
||||||
"Spec for file param created by ring.middleware.multipart-params.byte-array store."
|
"Spec for file param created by ring.middleware.multipart-params.byte-array store."
|
||||||
(st/spec
|
(st/spec
|
||||||
{:spec (s/keys :req-un [::filename ::content-type ::bytes])
|
{: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]
|
(defn- coerced-request [request coercers]
|
||||||
(if-let [coerced (if coercers (coercion/coerce-request coercers request))]
|
(if-let [coerced (if coercers (coercion/coerce-request coercers request))]
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@
|
||||||
(update $ :schema #(coercion/-compile-model this % nil))
|
(update $ :schema #(coercion/-compile-model this % nil))
|
||||||
$))]))})))
|
$))]))})))
|
||||||
:openapi (merge
|
:openapi (merge
|
||||||
(when (seq (dissoc parameters :body :request))
|
(when (seq (dissoc parameters :body :request :multipart))
|
||||||
(openapi/openapi-spec {::openapi/parameters
|
(openapi/openapi-spec {::openapi/parameters
|
||||||
(into (empty parameters)
|
(into (empty parameters)
|
||||||
(for [[k v] (dissoc parameters :body :request)]
|
(for [[k v] (dissoc parameters :body :request)]
|
||||||
|
|
@ -124,6 +124,12 @@
|
||||||
(into {}
|
(into {}
|
||||||
(for [[format model] (:content (:request parameters))]
|
(for [[format model] (:content (:request parameters))]
|
||||||
[format (coercion/-compile-model this model nil)])))})})
|
[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
|
(when responses
|
||||||
{:responses
|
{:responses
|
||||||
(into
|
(into
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
[reitit.coercion.malli :as malli]
|
[reitit.coercion.malli :as malli]
|
||||||
[reitit.coercion.schema :as schema]
|
[reitit.coercion.schema :as schema]
|
||||||
[reitit.coercion.spec :as spec]
|
[reitit.coercion.spec :as spec]
|
||||||
|
[reitit.http.interceptors.multipart]
|
||||||
[reitit.openapi :as openapi]
|
[reitit.openapi :as openapi]
|
||||||
[reitit.ring :as ring]
|
[reitit.ring :as ring]
|
||||||
[reitit.ring.spec]
|
[reitit.ring.spec]
|
||||||
|
|
@ -429,6 +430,39 @@
|
||||||
(testing "spec is valid"
|
(testing "spec is valid"
|
||||||
(is (nil? (validate spec))))))))
|
(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
|
(deftest per-content-type-test
|
||||||
(doseq [[coercion ->schema]
|
(doseq [[coercion ->schema]
|
||||||
[[#'malli/coercion (fn [nom] [:map [nom :string]])]
|
[[#'malli/coercion (fn [nom] [:map [nom :string]])]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue