Add OpenAPI :requestBody for :form request schema

OpenAPI Specification 3 requires defining form parameters, i.e. classic
application/x-www-form-urlencoded type body as a :requestBody. They are
not supported as regular parameters like in OAS 2.
This commit is contained in:
Markus Penttilä 2024-10-09 22:14:15 -04:00
parent d11deb3473
commit 702e7b8972
2 changed files with 25 additions and 2 deletions

View file

@ -76,10 +76,12 @@
(defn- openapi-path [path opts]
(-> path (trie/normalize opts) (str/replace #"\{\*" "{")))
(def ^:private form-content-type "application/x-www-form-urlencoded")
(defn -get-apidocs-openapi
[coercion {:keys [request muuntaja parameters responses openapi/request-content-types openapi/response-content-types]} definitions]
(let [{:keys [body multipart]} parameters
parameters (dissoc parameters :request :body :multipart)
(let [{:keys [body form multipart]} parameters
parameters (dissoc parameters :request :body :form :multipart)
->content (fn [data schema]
(merge
{:schema schema}
@ -122,6 +124,13 @@
[content-type {:schema schema}])))
request-content-types)}})
(when form
;; :form is similar to any other body, but the content type must be application/x-www-form-urlencoded
{:requestBody {:content {form-content-type {:schema (->schema-object form
{:in :requestBody
:type :schema
:content-type form-content-type})}}}})
(when request
;; :request allows different :requestBody per content-type
{:requestBody

View file

@ -739,6 +739,13 @@
:handler (fn [req]
{:status 200
:body (-> req :parameters :request)})}}]
["/form-params"
{:post {:description "ring :form-params coercion with :parameters :form syntax"
:coercion coercion
:parameters {:form (->schema :b)}
:handler (fn [req]
{:status 200
:body (-> req :parameters :request)})}}]
["/openapi.json"
{:get {:handler (openapi/create-openapi-handler)
:openapi {:info {:title "" :version "0.0.1"}}
@ -801,6 +808,13 @@
(-> spec
(get-in [:paths "/legacy" :post :responses 200 :content])
keys)))))
(testing ":parameters :form syntax"
(testing "body parameter"
(is (= ["application/x-www-form-urlencoded"]
(-> spec
(get-in [:paths "/form-params" :post :requestBody :content])
keys))
"form parameter schema is put under :requestBody with correct content type")))
(testing "spec is valid"
(is (nil? (validate spec))))))))