more robust apidocs

This commit is contained in:
Tommi Reiman 2018-07-30 11:09:40 +03:00
parent e879df54da
commit 4ea025dc83
3 changed files with 60 additions and 16 deletions

View file

@ -74,19 +74,19 @@
:or {extract-request-format extract-request-format-default
parameter-coercion default-parameter-coercion}}]
(if coercion
(let [{:keys [keywordize? open? in style]} (parameter-coercion type)
transform (comp (if keywordize? walk/keywordize-keys identity) in)
model (if open? (-open-model coercion model) model)
coercer (-request-coercer coercion style model)]
(fn [request]
(let [value (transform request)
format (extract-request-format request)
result (coercer value format)]
(if (error? result)
(request-coercion-failed! result coercion value in request)
result))))))
(if-let [{:keys [keywordize? open? in style]} (parameter-coercion type)]
(let [transform (comp (if keywordize? walk/keywordize-keys identity) in)
model (if open? (-open-model coercion model) model)
coercer (-request-coercer coercion style model)]
(fn [request]
(let [value (transform request)
format (extract-request-format request)
result (coercer value format)]
(if (error? result)
(request-coercion-failed! result coercion value in request)
result)))))))
(defn extract-response-format-default [request response]
(defn extract-response-format-default [request _]
(-> request :muuntaja/response :format))
(defn response-coercer [coercion body {:keys [extract-response-format]
@ -124,6 +124,7 @@
(->> (for [[k v] parameters
:when v]
[k (request-coercer coercion k v opts)])
(filter second)
(into {})))
(defn response-coercers [coercion responses opts]
@ -140,6 +141,28 @@
"{:compile reitit.coercion/compile-request-coercers}\n")
{:match match})))
;;
;; api-docs
;;
(defn get-apidocs [this spesification data]
(let [swagger-parameter {:query :query
:body :body
:form :formData
:header :header
:path :path
:multipart :formData}]
(case spesification
:swagger (->> (update
data
:parameters
(fn [parameters]
(->> parameters
(map (fn [[k v]] [(swagger-parameter k) v]))
(filter first)
(into {}))))
(-get-apidocs this spesification)))))
;;
;; integration
;;

View file

@ -77,19 +77,22 @@
(let [{:keys [id] :or {id ::default} :as swagger} (-> match :result request-method :data :swagger)
->set (fn [x] (if (or (set? x) (sequential? x)) (set x) (conj #{} x)))
ids (->set id)
swagger (->> (dissoc swagger :id)
strip-top-level-keys #(dissoc % :id :info :host :basePath :definitions :securityDefinitions)
strip-endpoint-keys #(dissoc % :id :parameters :responses :summary :description)
swagger (->> (strip-endpoint-keys swagger)
(merge {:swagger "2.0"
:x-id ids}))
accept-route #(-> % second :swagger :id (or ::default) ->set (set/intersection ids) seq)
accept-route (fn [route]
(-> route second :swagger :id (or ::default) ->set (set/intersection ids) seq))
transform-endpoint (fn [[method {{:keys [coercion no-doc swagger] :as data} :data middleware :middleware}]]
(if (and data (not no-doc))
[method
(meta-merge
(apply meta-merge (keep (comp :swagger :data) middleware))
(if coercion
(coercion/-get-apidocs coercion :swagger data))
(coercion/get-apidocs coercion :swagger data))
(select-keys data [:tags :summary :description])
(dissoc swagger :id))]))
(strip-top-level-keys swagger))]))
transform-path (fn [[p _ c]]
(if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))]
[(path->template p) endpoint]))]

View file

@ -182,3 +182,21 @@
(is (= #{::swagger/default}
(-> {:request-method :get :uri "/swagger.json"}
(app) :body :x-id)))))
(deftest all-parameter-types-test
(let [app (ring/ring-handler
(ring/router
[["/parameters"
{:post {:coercion spec/coercion
:parameters {:query {:q string?}
:body {:b string?}
:form {:f string?}
:header {:h string?}
:path {:p string?}}
:handler identity}}]
["/swagger.json"
{:get {:no-doc true
:handler (swagger/create-swagger-handler)}}]]))
spec (:body (app {:request-method :get, :uri "/swagger.json"}))]
(is (= ["query" "body" "formData" "header" "path"]
(map :in (get-in spec [:paths "/parameters" :post :parameters]))))))