From 702e7b8972b0ce50314e6d755ad1b08f0bf33848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Penttil=C3=A4?= Date: Wed, 9 Oct 2024 22:14:15 -0400 Subject: [PATCH] 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. --- modules/reitit-openapi/src/reitit/openapi.clj | 13 +++++++++++-- test/cljc/reitit/openapi_test.clj | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/modules/reitit-openapi/src/reitit/openapi.clj b/modules/reitit-openapi/src/reitit/openapi.clj index df7c01a4..979620eb 100644 --- a/modules/reitit-openapi/src/reitit/openapi.clj +++ b/modules/reitit-openapi/src/reitit/openapi.clj @@ -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 diff --git a/test/cljc/reitit/openapi_test.clj b/test/cljc/reitit/openapi_test.clj index 51247337..1b61f428 100644 --- a/test/cljc/reitit/openapi_test.clj +++ b/test/cljc/reitit/openapi_test.clj @@ -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))))))))