From 803ed0933a208909dc782869f4915adb9b1252e9 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Thu, 24 Aug 2023 11:05:43 +0300 Subject: [PATCH 1/7] refactor: parameterise -get-apidocs-openapi with ->schema-object --- modules/reitit-malli/src/reitit/coercion/malli.cljc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index e4f3ab2d..2198d3a6 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -138,17 +138,15 @@ ;; also, this has internally massive amount of duplicate code, could be simplified ;; ... tests too (defn -get-apidocs-openapi - [_ {:keys [request parameters responses content-types] :or {content-types ["application/json"]}} options] + [->schema-object {:keys [request parameters responses content-types] :or {content-types ["application/json"]}} options] (let [{:keys [body multipart]} parameters parameters (dissoc parameters :request :body :multipart) - ->schema-object (fn [schema opts] - (let [current-opts (merge options opts)] - (json-schema/transform schema current-opts))) ->content (fn [data schema] (merge {:schema schema} (select-keys data [:description :examples]) - (:openapi data)))] + (:openapi data))) + ->schema-object #(->schema-object %1 (merge options %2))] (merge (when (seq parameters) {:parameters @@ -263,7 +261,7 @@ (if (:schema $) (update $ :schema swagger/transform {:type :schema}) $))]))})) - :openapi (-get-apidocs-openapi this data options) + :openapi (-get-apidocs-openapi json-schema/transform data options) (throw (ex-info (str "Can't produce Schema apidocs for " specification) From ee298ec362266dddf2d8d5d00523f7833b82bbf8 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 08:32:58 +0300 Subject: [PATCH 2/7] refactor: Coercion.-get-model-apidocs, use it for malli openapi --- modules/reitit-core/src/reitit/coercion.cljc | 2 ++ .../reitit-malli/src/reitit/coercion/malli.cljc | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/modules/reitit-core/src/reitit/coercion.cljc b/modules/reitit-core/src/reitit/coercion.cljc index 75b78d79..f037983c 100644 --- a/modules/reitit-core/src/reitit/coercion.cljc +++ b/modules/reitit-core/src/reitit/coercion.cljc @@ -13,6 +13,8 @@ (-get-name [this] "Keyword name for the coercion") (-get-options [this] "Coercion options") (-get-apidocs [this specification data] "Returns api documentation") + ;; TODO doc options: + (-get-model-apidocs [this specification model options] "Convert model into a format that can be used in api docs") (-compile-model [this model name] "Compiles a model") (-open-model [this model] "Returns a new model which allows extra keys in maps") (-encode-error [this error] "Converts error in to a serializable format") diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index 2198d3a6..e8bc2b1f 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -138,7 +138,7 @@ ;; also, this has internally massive amount of duplicate code, could be simplified ;; ... tests too (defn -get-apidocs-openapi - [->schema-object {:keys [request parameters responses content-types] :or {content-types ["application/json"]}} options] + [coercion {:keys [request parameters responses content-types] :or {content-types ["application/json"]}} options] (let [{:keys [body multipart]} parameters parameters (dissoc parameters :request :body :multipart) ->content (fn [data schema] @@ -146,7 +146,7 @@ {:schema schema} (select-keys data [:description :examples]) (:openapi data))) - ->schema-object #(->schema-object %1 (merge options %2))] + ->schema-object #(coercion/-get-model-apidocs coercion :openapi %1 (merge options %2))] (merge (when (seq parameters) {:parameters @@ -241,6 +241,13 @@ (reify coercion/Coercion (-get-name [_] :malli) (-get-options [_] opts) + (-get-model-apidocs [this specification model options] + (case specification + :openapi (json-schema/transform model options) + (throw + (ex-info + (str "Can't produce Malli apidocs for " specification) + {:type specification, :coercion :malli})))) (-get-apidocs [this specification {:keys [parameters responses] :as data}] (case specification :swagger (merge @@ -261,11 +268,11 @@ (if (:schema $) (update $ :schema swagger/transform {:type :schema}) $))]))})) - :openapi (-get-apidocs-openapi json-schema/transform data options) + :openapi (-get-apidocs-openapi this data options) (throw (ex-info - (str "Can't produce Schema apidocs for " specification) - {:type specification, :coercion :schema})))) + (str "Can't produce Malli apidocs for " specification) + {:type specification, :coercion :malli})))) (-compile-model [_ model _] (if (= 1 (count model)) (compile (first model) options) From f943b025cbc23a29503dd7f5c9e97879a70ab504 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 08:59:58 +0300 Subject: [PATCH 3/7] refactor: no need to pass options into -get-apidocs-openapi --- modules/reitit-malli/src/reitit/coercion/malli.cljc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index e8bc2b1f..c033c5c1 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -133,12 +133,8 @@ ;; malli options :options nil}) -;; TODO: this is now seems like a generic transforming function that could be used in all of malli, spec, schema -;; ... just tranform the schemas in place -;; also, this has internally massive amount of duplicate code, could be simplified -;; ... tests too (defn -get-apidocs-openapi - [coercion {:keys [request parameters responses content-types] :or {content-types ["application/json"]}} options] + [coercion {:keys [request parameters responses content-types] :or {content-types ["application/json"]}}] (let [{:keys [body multipart]} parameters parameters (dissoc parameters :request :body :multipart) ->content (fn [data schema] @@ -146,7 +142,7 @@ {:schema schema} (select-keys data [:description :examples]) (:openapi data))) - ->schema-object #(coercion/-get-model-apidocs coercion :openapi %1 (merge options %2))] + ->schema-object #(coercion/-get-model-apidocs coercion :openapi %1 %2)] (merge (when (seq parameters) {:parameters @@ -243,7 +239,7 @@ (-get-options [_] opts) (-get-model-apidocs [this specification model options] (case specification - :openapi (json-schema/transform model options) + :openapi (json-schema/transform model (merge opts options)) (throw (ex-info (str "Can't produce Malli apidocs for " specification) @@ -268,7 +264,7 @@ (if (:schema $) (update $ :schema swagger/transform {:type :schema}) $))]))})) - :openapi (-get-apidocs-openapi this data options) + :openapi (-get-apidocs-openapi this data) (throw (ex-info (str "Can't produce Malli apidocs for " specification) From 051452231a073b1e15563db953cfebd541641482 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 09:02:11 +0300 Subject: [PATCH 4/7] refactor: -get-model-apidocs for schema & spec not used yet tho --- modules/reitit-schema/src/reitit/coercion/schema.cljc | 7 +++++++ modules/reitit-spec/src/reitit/coercion/spec.cljc | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/modules/reitit-schema/src/reitit/coercion/schema.cljc b/modules/reitit-schema/src/reitit/coercion/schema.cljc index e0822ad9..24acf220 100644 --- a/modules/reitit-schema/src/reitit/coercion/schema.cljc +++ b/modules/reitit-schema/src/reitit/coercion/schema.cljc @@ -47,6 +47,13 @@ (reify coercion/Coercion (-get-name [_] :schema) (-get-options [_] opts) + (-get-model-apidocs [_ specification model options] + (case specification + :openapi (openapi/transform model (merge opts options)) + (throw + (ex-info + (str "Can't produce Schema apidocs for " specification) + {:type specification, :coercion :schema})))) (-get-apidocs [_ specification {:keys [request parameters responses content-types] :or {content-types ["application/json"]}}] ;; TODO: this looks identical to spec, refactor when schema is done. diff --git a/modules/reitit-spec/src/reitit/coercion/spec.cljc b/modules/reitit-spec/src/reitit/coercion/spec.cljc index 98ff9e37..da5cfdd1 100644 --- a/modules/reitit-spec/src/reitit/coercion/spec.cljc +++ b/modules/reitit-spec/src/reitit/coercion/spec.cljc @@ -88,6 +88,13 @@ (reify coercion/Coercion (-get-name [_] :spec) (-get-options [_] opts) + (-get-model-apidocs [_ specification model options] + (case specification + :openapi (openapi/transform model (merge opts options)) + (throw + (ex-info + (str "Can't produce Spec apidocs for " specification) + {:type specification, :coercion :spec})))) (-get-apidocs [_ specification {:keys [request parameters responses content-types] :or {content-types ["application/json"]}}] (case specification From 6f111bce2ec2bdc9b23b74f323f65170843cd82f Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 09:24:10 +0300 Subject: [PATCH 5/7] refactor: share -get-apidocs-openapi between malli, spec & schema --- .../src/reitit/coercion/malli.cljc | 92 +------------------ .../reitit-openapi/src/reitit/openapi.cljc | 92 ++++++++++++++++++- test/cljc/reitit/openapi_test.clj | 12 +-- 3 files changed, 94 insertions(+), 102 deletions(-) diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index c033c5c1..89c65cb5 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -133,96 +133,6 @@ ;; malli options :options nil}) -(defn -get-apidocs-openapi - [coercion {:keys [request parameters responses content-types] :or {content-types ["application/json"]}}] - (let [{:keys [body multipart]} parameters - parameters (dissoc parameters :request :body :multipart) - ->content (fn [data schema] - (merge - {:schema schema} - (select-keys data [:description :examples]) - (:openapi data))) - ->schema-object #(coercion/-get-model-apidocs coercion :openapi %1 %2)] - (merge - (when (seq parameters) - {:parameters - (->> (for [[in schema] parameters - :let [{:keys [properties required]} (->schema-object schema {:in in :type :parameter}) - required? (partial contains? (set required))] - [k schema] properties] - (merge {:in (name in) - :name k - :required (required? k) - :schema schema} - (select-keys schema [:description]))) - (into []))}) - (when body - ;; body uses a single schema to describe every :requestBody - ;; the schema-object transformer should be able to transform into distinct content-types - {:requestBody {:content (into {} - (map (fn [content-type] - (let [schema (->schema-object body {:in :requestBody - :type :schema - :content-type content-type})] - [content-type {:schema schema}]))) - content-types)}}) - - (when request - ;; request allow to different :requestBody per content-type - {:requestBody - {:content (merge - (select-keys request [:description]) - (when-let [{:keys [schema] :as data} (coercion/get-default request)] - (into {} - (map (fn [content-type] - (let [schema (->schema-object schema {:in :requestBody - :type :schema - :content-type content-type})] - [content-type (->content data schema)]))) - content-types)) - (into {} - (map (fn [[content-type {:keys [schema] :as data}]] - (let [schema (->schema-object schema {:in :requestBody - :type :schema - :content-type content-type})] - [content-type (->content data schema)]))) - (:content request)))}}) - (when multipart - {:requestBody - {:content - {"multipart/form-data" - {:schema - (->schema-object multipart {:in :requestBody - :type :schema - :content-type "multipart/form-data"})}}}}) - (when responses - {:responses - (into {} - (map (fn [[status {:keys [content], :as response}]] - (let [default (coercion/get-default-schema response) - content (-> (merge - (when default - (into {} - (map (fn [content-type] - (let [schema (->schema-object default {:in :responses - :type :schema - :content-type content-type})] - [content-type (->content nil schema)]))) - content-types)) - (when content - (into {} - (map (fn [[content-type {:keys [schema] :as data}]] - (let [schema (->schema-object schema {:in :responses - :type :schema - :content-type content-type})] - [content-type (->content data schema)]))) - content))) - (dissoc :default))] - [status (merge (select-keys response [:description]) - (when content - {:content content}))])) - responses))})))) - (defn create ([] (create nil)) @@ -264,7 +174,7 @@ (if (:schema $) (update $ :schema swagger/transform {:type :schema}) $))]))})) - :openapi (-get-apidocs-openapi this data) + ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw (ex-info (str "Can't produce Malli apidocs for " specification) diff --git a/modules/reitit-openapi/src/reitit/openapi.cljc b/modules/reitit-openapi/src/reitit/openapi.cljc index 89bfd3df..68dc2caa 100644 --- a/modules/reitit-openapi/src/reitit/openapi.cljc +++ b/modules/reitit-openapi/src/reitit/openapi.cljc @@ -73,6 +73,96 @@ (defn- openapi-path [path opts] (-> path (trie/normalize opts) (str/replace #"\{\*" "{"))) +(defn -get-apidocs-openapi + [coercion {:keys [request parameters responses content-types] :or {content-types ["application/json"]}}] + (let [{:keys [body multipart]} parameters + parameters (dissoc parameters :request :body :multipart) + ->content (fn [data schema] + (merge + {:schema schema} + (select-keys data [:description :examples]) + (:openapi data))) + ->schema-object #(coercion/-get-model-apidocs coercion :openapi %1 %2)] + (merge + (when (seq parameters) + {:parameters + (->> (for [[in schema] parameters + :let [{:keys [properties required]} (->schema-object schema {:in in :type :parameter}) + required? (partial contains? (set required))] + [k schema] properties] + (merge {:in (name in) + :name k + :required (required? k) + :schema schema} + (select-keys schema [:description]))) + (into []))}) + (when body + ;; body uses a single schema to describe every :requestBody + ;; the schema-object transformer should be able to transform into distinct content-types + {:requestBody {:content (into {} + (map (fn [content-type] + (let [schema (->schema-object body {:in :requestBody + :type :schema + :content-type content-type})] + [content-type {:schema schema}]))) + content-types)}}) + + (when request + ;; request allow to different :requestBody per content-type + {:requestBody + {:content (merge + (select-keys request [:description]) + (when-let [{:keys [schema] :as data} (coercion/get-default request)] + (into {} + (map (fn [content-type] + (let [schema (->schema-object schema {:in :requestBody + :type :schema + :content-type content-type})] + [content-type (->content data schema)]))) + content-types)) + (into {} + (map (fn [[content-type {:keys [schema] :as data}]] + (let [schema (->schema-object schema {:in :requestBody + :type :schema + :content-type content-type})] + [content-type (->content data schema)]))) + (:content request)))}}) + (when multipart + {:requestBody + {:content + {"multipart/form-data" + {:schema + (->schema-object multipart {:in :requestBody + :type :schema + :content-type "multipart/form-data"})}}}}) + (when responses + {:responses + (into {} + (map (fn [[status {:keys [content], :as response}]] + (let [default (coercion/get-default-schema response) + content (-> (merge + (when default + (into {} + (map (fn [content-type] + (let [schema (->schema-object default {:in :responses + :type :schema + :content-type content-type})] + [content-type (->content nil schema)]))) + content-types)) + (when content + (into {} + (map (fn [[content-type {:keys [schema] :as data}]] + (let [schema (->schema-object schema {:in :responses + :type :schema + :content-type content-type})] + [content-type (->content data schema)]))) + content))) + (dissoc :default))] + [status (merge (select-keys response [:description]) + (when content + {:content content}))])) + responses))})))) + (defn create-openapi-handler "Stability: alpha @@ -99,7 +189,7 @@ (apply meta-merge (keep (comp :openapi :data) middleware)) (apply meta-merge (keep (comp :openapi :data) interceptors)) (if coercion - (coercion/get-apidocs coercion :openapi data)) + (-get-apidocs-openapi coercion data)) (select-keys data [:tags :summary :description]) (strip-top-level-keys openapi))])) transform-path (fn [[p _ c]] diff --git a/test/cljc/reitit/openapi_test.clj b/test/cljc/reitit/openapi_test.clj index f147c407..3724b7ac 100644 --- a/test/cljc/reitit/openapi_test.clj +++ b/test/cljc/reitit/openapi_test.clj @@ -157,19 +157,16 @@ :version "0.0.1"} :paths {"/api/spec/plus/{z}" {:get {:parameters [{:in "query" :name "x" - :description "" :required true :schema {:type "integer" :format "int64"}} {:in "query" :name "y" - :description "" :required true :schema {:type "integer" :format "int64"}} {:in "path" :name "z" - :description "" :required true :schema {:type "integer" :format "int64"}}] @@ -188,7 +185,6 @@ :post {:parameters [{:in "path" :name "z" :required true - :description "" :schema {:type "integer" :format "int64"}}] :requestBody {:content {"application/json" {:schema {:oneOf [{:items {:type "integer" @@ -251,21 +247,18 @@ :required [:error] :type "object"}}}}} :summary "plus with body"}} - "/api/schema/plus/{z}" {:get {:parameters [{:description "" - :in "query" + "/api/schema/plus/{z}" {:get {:parameters [{:in "query" :name "x" :required true :schema {:format "int32" :type "integer"}} - {:description "" - :in "query" + {:in "query" :name "y" :required true :schema {:type "integer" :format "int32"}} {:in "path" :name "z" - :description "" :required true :schema {:type "integer" :format "int32"}}] @@ -282,7 +275,6 @@ :summary "plus"} :post {:parameters [{:in "path" :name "z" - :description "" :required true :schema {:type "integer" :format "int32"}}] From 233ac19914971813f9ccddfff86e060559120e08 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 10:03:07 +0300 Subject: [PATCH 6/7] refactor: remove dead code --- modules/reitit-core/src/reitit/coercion.cljc | 2 +- .../src/reitit/coercion/schema.cljc | 37 +------------------ .../reitit-spec/src/reitit/coercion/spec.cljc | 37 +------------------ 3 files changed, 3 insertions(+), 73 deletions(-) diff --git a/modules/reitit-core/src/reitit/coercion.cljc b/modules/reitit-core/src/reitit/coercion.cljc index f037983c..694a529d 100644 --- a/modules/reitit-core/src/reitit/coercion.cljc +++ b/modules/reitit-core/src/reitit/coercion.cljc @@ -209,7 +209,7 @@ :path :path :multipart :formData}] (case specification - :openapi (-get-apidocs coercion specification data) + ;; :openapi handled in reitit.openapi :swagger (do (-warn-unsupported-coercions data) (->> (update diff --git a/modules/reitit-schema/src/reitit/coercion/schema.cljc b/modules/reitit-schema/src/reitit/coercion/schema.cljc index 24acf220..edd5f72e 100644 --- a/modules/reitit-schema/src/reitit/coercion/schema.cljc +++ b/modules/reitit-schema/src/reitit/coercion/schema.cljc @@ -68,42 +68,7 @@ (empty responses) (for [[k response] responses] [k (set/rename-keys response {:body :schema})]))}))) - :openapi (merge - (when (seq (dissoc parameters :body :request :multipart)) - (openapi/openapi-spec {::openapi/parameters (dissoc parameters :body :request)})) - (when (:body parameters) - {:requestBody (openapi/openapi-spec - {::openapi/content (zipmap content-types (repeat (:body parameters)))})}) - (when request - {:requestBody (openapi/openapi-spec - {::openapi/content (merge - (when-let [default (coercion/get-default-schema request)] - (zipmap content-types (repeat default))) - (->> (for [[content-type {:keys [schema]}] (:content request)] - [content-type schema]) - (into {})))})}) - (when (:multipart parameters) - {:requestBody - (openapi/openapi-spec - {::openapi/content {"multipart/form-data" (:multipart parameters)}})}) - (when responses - {:responses - (into - (empty responses) - (for [[k {:keys [content] :as response}] responses - :let [default (coercion/get-default-schema response)]] - [k (merge - (select-keys response [:description]) - (when (or content default) - (openapi/openapi-spec - {::openapi/content (-> (merge - (when default - (zipmap content-types (repeat default))) - (->> (for [[content-type {:keys [schema]}] content] - [content-type schema]) - (into {}))) - (dissoc :default))})))]))})) - + ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw (ex-info (str "Can't produce Schema apidocs for " specification) diff --git a/modules/reitit-spec/src/reitit/coercion/spec.cljc b/modules/reitit-spec/src/reitit/coercion/spec.cljc index da5cfdd1..ba251675 100644 --- a/modules/reitit-spec/src/reitit/coercion/spec.cljc +++ b/modules/reitit-spec/src/reitit/coercion/spec.cljc @@ -109,42 +109,7 @@ (for [[k response] responses] [k (as-> response $ (set/rename-keys $ {:body :schema}))]))}))) - :openapi (merge - (when (seq (dissoc parameters :body :request :multipart)) - (openapi/openapi-spec {::openapi/parameters (dissoc parameters :body :request)})) - (when (:body parameters) - {:requestBody (openapi/openapi-spec - {::openapi/content (zipmap content-types (repeat (:body parameters)))})}) - (when request - {:requestBody (openapi/openapi-spec - {::openapi/content (merge - (when-let [default (coercion/get-default-schema request)] - (zipmap content-types (repeat default))) - (->> (for [[content-type {:keys [schema]}] (:content request)] - [content-type schema]) - (into {})))})}) - (when (:multipart parameters) - {:requestBody - (openapi/openapi-spec - {::openapi/content {"multipart/form-data" (:multipart parameters)}})}) - (when responses - {:responses - (into - (empty responses) - (for [[k {:keys [content] :as response}] responses - :let [default (coercion/get-default-schema response) - content-types (remove #{:default} content-types)]] - [k (merge - (select-keys response [:description]) - (when (or content default) - (openapi/openapi-spec - {::openapi/content (-> (merge - (when default - (zipmap content-types (repeat default))) - (->> (for [[content-type {:keys [schema]}] content] - [content-type schema]) - (into {}))) - (dissoc :default))})))]))})) + ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw (ex-info (str "Can't produce Spec apidocs for " specification) From 8af89c05cbda9820ee4d4a4c0ae40c430b9a5e01 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Mon, 28 Aug 2023 10:04:37 +0300 Subject: [PATCH 7/7] refactor: get rid of reitit.coercion/get-apidocs --- modules/reitit-core/src/reitit/coercion.cljc | 31 ------------------- .../reitit-swagger/src/reitit/swagger.cljc | 26 +++++++++++++++- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/modules/reitit-core/src/reitit/coercion.cljc b/modules/reitit-core/src/reitit/coercion.cljc index 694a529d..2bf11482 100644 --- a/modules/reitit-core/src/reitit/coercion.cljc +++ b/modules/reitit-core/src/reitit/coercion.cljc @@ -191,37 +191,6 @@ (defn -compile-parameters [data coercion] (impl/path-update data [[[:parameters any?] #(-compile-model coercion % nil)]])) -;; -;; api-docs -;; - -(defn -warn-unsupported-coercions [{:keys [request responses] :as _data}] - (when request - (println "WARNING [reitit.coercion]: swagger apidocs don't support :request coercion")) - (when (some :content (vals responses)) - (println "WARNING [reitit.coercion]: swagger apidocs don't support :responses :content coercion"))) - -(defn get-apidocs [coercion specification data] - (let [swagger-parameter {:query :query - :body :body - :form :formData - :header :header - :path :path - :multipart :formData}] - (case specification - ;; :openapi handled in reitit.openapi - :swagger (do - (-warn-unsupported-coercions data) - (->> (update - data - :parameters - (fn [parameters] - (->> parameters - (map (fn [[k v]] [(swagger-parameter k) v])) - (filter first) - (into {})))) - (-get-apidocs coercion specification)))))) - ;; ;; integration ;; diff --git a/modules/reitit-swagger/src/reitit/swagger.cljc b/modules/reitit-swagger/src/reitit/swagger.cljc index 3c3403cb..9525035b 100644 --- a/modules/reitit-swagger/src/reitit/swagger.cljc +++ b/modules/reitit-swagger/src/reitit/swagger.cljc @@ -69,6 +69,30 @@ (defn- swagger-path [path opts] (-> path (trie/normalize opts) (str/replace #"\{\*" "{"))) +(defn -warn-unsupported-coercions [{:keys [request responses] :as _data}] + (when request + (println "WARNING [reitit.coercion]: swagger apidocs don't support :request coercion")) + (when (some :content (vals responses)) + (println "WARNING [reitit.coercion]: swagger apidocs don't support :responses :content coercion"))) + +(defn -get-swagger-apidocs [coercion data] + (let [swagger-parameter {:query :query + :body :body + :form :formData + :header :header + :path :path + :multipart :formData}] + (-warn-unsupported-coercions data) + (->> (update + data + :parameters + (fn [parameters] + (->> parameters + (map (fn [[k v]] [(swagger-parameter k) v])) + (filter first) + (into {})))) + (coercion/-get-apidocs coercion :swagger)))) + (defn create-swagger-handler "Create a ring handler to emit swagger spec. Collects all routes from router which have an intersecting `[:swagger :id]` and which are not marked with `:no-doc` route data." @@ -95,7 +119,7 @@ (apply meta-merge (keep (comp :swagger :data) middleware)) (apply meta-merge (keep (comp :swagger :data) interceptors)) (if coercion - (coercion/get-apidocs coercion :swagger data)) + (-get-swagger-apidocs coercion data)) (select-keys data [:tags :summary :description :operationId]) (strip-top-level-keys swagger))])) transform-path (fn [[p _ c]]