Merge pull request #642 from metosin/rework-pr-589

Fix malli swagger defs w/ custom registries
This commit is contained in:
Joel Kaasinen 2023-09-01 15:45:49 +03:00 committed by GitHub
commit f2e6d335f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 53 deletions

View file

@ -76,33 +76,6 @@
(assoc error :transformed transformed)))) (assoc error :transformed transformed))))
value)))))))) value))))))))
;;
;; swagger
;;
(defmulti extract-parameter (fn [in _ _] in))
(defmethod extract-parameter :body [_ schema options]
(let [swagger-schema (swagger/transform schema (merge options {:in :body, :type :parameter}))]
[{:in "body"
:name (:title swagger-schema "body")
:description (:description swagger-schema "")
:required (not= :maybe (m/type schema))
:schema swagger-schema}]))
(defmethod extract-parameter :default [in schema options]
(let [{:keys [properties required]} (swagger/transform schema (merge options {:in in, :type :parameter}))]
(mapv
(fn [[k {:keys [type] :as schema}]]
(merge
{:in (name in)
:name k
:description (:description schema "")
:type type
:required (contains? (set required) k)}
schema))
properties)))
;; ;;
;; public api ;; public api
;; ;;
@ -156,25 +129,24 @@
{:type specification, :coercion :malli})))) {:type specification, :coercion :malli}))))
(-get-apidocs [this specification {:keys [parameters responses] :as data}] (-get-apidocs [this specification {:keys [parameters responses] :as data}]
(case specification (case specification
:swagger (merge :swagger (swagger/swagger-spec
(if parameters (merge
{:parameters (if parameters
(->> (for [[in schema] parameters {::swagger/parameters
parameter (extract-parameter in schema options)] (into
parameter) (empty parameters)
(into []))}) (for [[k v] parameters]
(if responses [k (compile v options)]))})
{:responses (if responses
(into {::swagger/responses
(empty responses) (into
(for [[status response] responses] (empty responses)
[status (as-> response $ (for [[k response] responses]
(set/rename-keys $ {:body :schema}) [k (as-> response $
(dissoc $ :content) (set/rename-keys $ {:body :schema})
(update $ :description (fnil identity "")) (if (:schema $)
(if (:schema $) (update $ :schema compile options)
(update $ :schema swagger/transform {:type :schema}) $))]))})))
$))]))}))
;; :openapi handled in reitit.openapi/-get-apidocs-openapi ;; :openapi handled in reitit.openapi/-get-apidocs-openapi
(throw (throw
(ex-info (ex-info

View file

@ -126,9 +126,15 @@
(if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))] (if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))]
[(swagger-path p (r/options router)) endpoint])) [(swagger-path p (r/options router)) endpoint]))
map-in-order #(->> % (apply concat) (apply array-map)) map-in-order #(->> % (apply concat) (apply array-map))
paths (->> router (r/compiled-routes) (filter accept-route) (map transform-path) map-in-order)] paths (->> router (r/compiled-routes) (filter accept-route) (map transform-path) map-in-order)
definitions (apply merge
(for [[_path path-data] paths
[_method data] path-data]
(:definitions data)))
paths-without-definitions (update-vals paths (fn [methods]
(update-vals methods #(dissoc % :definitions))))]
{:status 200 {:status 200
:body (meta-merge swagger {:paths paths})})) :body (meta-merge swagger {:paths paths-without-definitions :definitions definitions})}))
([req res raise] ([req res raise]
(try (try
(res (create-swagger req)) (res (create-swagger req))

View file

@ -37,7 +37,7 @@
[metosin/muuntaja "0.6.8"] [metosin/muuntaja "0.6.8"]
[metosin/jsonista "0.3.7"] [metosin/jsonista "0.3.7"]
[metosin/sieppari "0.0.0-alpha13"] [metosin/sieppari "0.0.0-alpha13"]
[metosin/malli "0.11.0"] [metosin/malli "0.12.0"]
;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111 ;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
[com.fasterxml.jackson.core/jackson-core "2.15.1"] [com.fasterxml.jackson.core/jackson-core "2.15.1"]
@ -95,7 +95,7 @@
[metosin/muuntaja "0.6.8"] [metosin/muuntaja "0.6.8"]
[metosin/sieppari "0.0.0-alpha13"] [metosin/sieppari "0.0.0-alpha13"]
[metosin/jsonista "0.3.7"] [metosin/jsonista "0.3.7"]
[metosin/malli "0.11.0"] [metosin/malli "0.12.0"]
[lambdaisland/deep-diff "0.0-47"] [lambdaisland/deep-diff "0.0-47"]
[meta-merge "1.0.0"] [meta-merge "1.0.0"]
[com.bhauman/spell-spec "0.1.2"] [com.bhauman/spell-spec "0.1.2"]

View file

@ -12,7 +12,8 @@
[reitit.swagger :as swagger] [reitit.swagger :as swagger]
[reitit.swagger-ui :as swagger-ui] [reitit.swagger-ui :as swagger-ui]
[schema.core :as s] [schema.core :as s]
[spec-tools.data-spec :as ds])) [spec-tools.data-spec :as ds]
[malli.core :as mc]))
(defn- normalize (defn- normalize
"Normalize format of swagger spec by converting it to json and back. "Normalize format of swagger spec by converting it to json and back.
@ -22,6 +23,23 @@
j/write-value-as-string j/write-value-as-string
(j/read-value j/keyword-keys-object-mapper))) (j/read-value j/keyword-keys-object-mapper)))
(def malli-registry
(merge
(mc/base-schemas)
(mc/predicate-schemas)
(mc/type-schemas)
{::req-key [:or :keyword :string]
::req-val [:or map? :string]
::resp-map map?
::resp-string [:string {:min 1}]}))
(def PutReqBody
(mc/schema [:map-of ::req-key ::req-val] {:registry malli-registry}))
(def PutRespBody
(mc/schema [:or ::resp-map ::resp-string] {:registry malli-registry}))
(def app (def app
(ring/ring-handler (ring/ring-handler
(ring/router (ring/router
@ -84,7 +102,13 @@
500 {:description "fail"}} 500 {:description "fail"}}
:handler (fn [{{{:keys [z]} :path :handler (fn [{{{:keys [z]} :path
xs :body} :parameters}] xs :body} :parameters}]
{:status 200, :body {:total (+ (reduce + xs) z)}})}}]] {:status 200, :body {:total (+ (reduce + xs) z)}})}
:put {:summary "plus put with definitions"
:parameters {:body PutReqBody}
:responses {200 {:body PutRespBody}
500 {:description "fail"}}
:handler (fn [{{body :body} :parameters}]
{:status 200, :body (str "got " body)})}}]]
["/schema" {:coercion schema/coercion} ["/schema" {:coercion schema/coercion}
["/plus/*z" ["/plus/*z"
@ -137,6 +161,15 @@
expected {:x-id #{::math} expected {:x-id #{::math}
:swagger "2.0" :swagger "2.0"
:info {:title "my-api"} :info {:title "my-api"}
:definitions {::req-key {:type "string"
:x-anyOf [{:type "string"}
{:type "string"}]}
::req-val {:type "object"
:x-anyOf [{:type "object"}
{:type "string"}]}
::resp-map {:type "object"},
::resp-string {:type "string"
:minLength 1}}
:paths {"/api/spec/plus/{z}" {:patch {:parameters [] :paths {"/api/spec/plus/{z}" {:patch {:parameters []
:summary "patch" :summary "patch"
:operationId "Patch" :operationId "Patch"
@ -246,7 +279,23 @@
400 {:schema {:type "string"} 400 {:schema {:type "string"}
:description "kosh"} :description "kosh"}
500 {:description "fail"}} 500 {:description "fail"}}
:summary "plus with body"}} :summary "plus with body"}
:put {:parameters [{:in "body"
:name "body"
:description ""
:required true
:schema
{:type "object"
:additionalProperties
{:$ref "#/definitions/reitit.swagger-test~1req-val"}}}]
:responses {200
{:schema
{:$ref "#/definitions/reitit.swagger-test~1resp-map"
:x-anyOf [{:$ref "#/definitions/reitit.swagger-test~1resp-map"}
{:$ref "#/definitions/reitit.swagger-test~1resp-string"}]}
:description ""}
500 {:description "fail"}}
:summary "plus put with definitions"}}
"/api/schema/plus/{z}" {:get {:parameters [{:description "" "/api/schema/plus/{z}" {:get {:parameters [{:description ""
:format "int32" :format "int32"
:in "query" :in "query"