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 :or {extract-request-format extract-request-format-default
parameter-coercion default-parameter-coercion}}] parameter-coercion default-parameter-coercion}}]
(if coercion (if coercion
(let [{:keys [keywordize? open? in style]} (parameter-coercion type) (if-let [{:keys [keywordize? open? in style]} (parameter-coercion type)]
transform (comp (if keywordize? walk/keywordize-keys identity) in) (let [transform (comp (if keywordize? walk/keywordize-keys identity) in)
model (if open? (-open-model coercion model) model) model (if open? (-open-model coercion model) model)
coercer (-request-coercer coercion style model)] coercer (-request-coercer coercion style model)]
(fn [request] (fn [request]
(let [value (transform request) (let [value (transform request)
format (extract-request-format request) format (extract-request-format request)
result (coercer value format)] result (coercer value format)]
(if (error? result) (if (error? result)
(request-coercion-failed! result coercion value in request) (request-coercion-failed! result coercion value in request)
result)))))) result)))))))
(defn extract-response-format-default [request response] (defn extract-response-format-default [request _]
(-> request :muuntaja/response :format)) (-> request :muuntaja/response :format))
(defn response-coercer [coercion body {:keys [extract-response-format] (defn response-coercer [coercion body {:keys [extract-response-format]
@ -124,6 +124,7 @@
(->> (for [[k v] parameters (->> (for [[k v] parameters
:when v] :when v]
[k (request-coercer coercion k v opts)]) [k (request-coercer coercion k v opts)])
(filter second)
(into {}))) (into {})))
(defn response-coercers [coercion responses opts] (defn response-coercers [coercion responses opts]
@ -140,6 +141,28 @@
"{:compile reitit.coercion/compile-request-coercers}\n") "{:compile reitit.coercion/compile-request-coercers}\n")
{:match match}))) {: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 ;; integration
;; ;;

View file

@ -77,19 +77,22 @@
(let [{:keys [id] :or {id ::default} :as swagger} (-> match :result request-method :data :swagger) (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))) ->set (fn [x] (if (or (set? x) (sequential? x)) (set x) (conj #{} x)))
ids (->set id) 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" (merge {:swagger "2.0"
:x-id ids})) :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}]] transform-endpoint (fn [[method {{:keys [coercion no-doc swagger] :as data} :data middleware :middleware}]]
(if (and data (not no-doc)) (if (and data (not no-doc))
[method [method
(meta-merge (meta-merge
(apply meta-merge (keep (comp :swagger :data) middleware)) (apply meta-merge (keep (comp :swagger :data) middleware))
(if coercion (if coercion
(coercion/-get-apidocs coercion :swagger data)) (coercion/get-apidocs coercion :swagger data))
(select-keys data [:tags :summary :description]) (select-keys data [:tags :summary :description])
(dissoc swagger :id))])) (strip-top-level-keys swagger))]))
transform-path (fn [[p _ c]] transform-path (fn [[p _ c]]
(if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))] (if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))]
[(path->template p) endpoint]))] [(path->template p) endpoint]))]

View file

@ -182,3 +182,21 @@
(is (= #{::swagger/default} (is (= #{::swagger/default}
(-> {:request-method :get :uri "/swagger.json"} (-> {:request-method :get :uri "/swagger.json"}
(app) :body :x-id))))) (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]))))))