mirror of
https://github.com/metosin/reitit.git
synced 2025-12-20 01:21:11 +00:00
Initial swagger-ui integration
This commit is contained in:
parent
0b711b2560
commit
05fbaa1110
6 changed files with 71 additions and 22 deletions
|
|
@ -3,6 +3,5 @@
|
|||
:dependencies [[org.clojure/clojure "1.9.0"]
|
||||
[ring "1.6.3"]
|
||||
[metosin/muuntaja "0.5.0"]
|
||||
[org.webjars/swagger-ui "3.13.6"]
|
||||
[metosin/reitit "0.1.1-SNAPSHOT"]]
|
||||
:repl-options {:init-ns example.server})
|
||||
|
|
|
|||
|
|
@ -21,26 +21,29 @@
|
|||
:swagger {:info {:title "my-api"}}
|
||||
:handler (swagger/create-swagger-handler)}}]
|
||||
|
||||
["/spec" {:coercion spec/coercion}
|
||||
["/spec"
|
||||
{:coercion spec/coercion
|
||||
:swagger {:tags ["spec"]}}
|
||||
|
||||
["/plus"
|
||||
{:get {:summary "plus"
|
||||
{:get {:summary "plus with spec"
|
||||
:parameters {:query {:x int?, :y int?}}
|
||||
:responses {200 {:body {:total int?}}}
|
||||
:handler (fn [{{{:keys [x y]} :query} :parameters}]
|
||||
{:status 200, :body {:total (+ x y)}})}}]]
|
||||
{:status 200
|
||||
:body {:total (+ x y)}})}}]]
|
||||
|
||||
["/schema"
|
||||
{:coercion schema/coercion
|
||||
:swagger {:tags ["schema"]}}
|
||||
|
||||
["/schema" {:coercion schema/coercion}
|
||||
["/plus"
|
||||
{:get {:summary "plus"
|
||||
{:get {:summary "plus with schema"
|
||||
:parameters {:query {:x Int, :y Int}}
|
||||
:responses {200 {:body {:total Int}}}
|
||||
:handler (fn [{{{:keys [x y]} :query} :parameters}]
|
||||
{:status 200, :body {:total (+ x y)}})}}]]]
|
||||
|
||||
["/api-docs/*"
|
||||
{:no-doc true
|
||||
:handler (ring/create-resource-handler
|
||||
{:root "META-INF/resources/webjars/swagger-ui/3.13.6"})}]]
|
||||
{:status 200
|
||||
:body {:total (+ x y)}})}}]]]]
|
||||
|
||||
{:data {:middleware [ring.middleware.params/wrap-params
|
||||
muuntaja.middleware/wrap-format
|
||||
|
|
@ -49,7 +52,8 @@
|
|||
rrc/coerce-request-middleware
|
||||
rrc/coerce-response-middleware]}})
|
||||
(ring/routes
|
||||
(ring/create-resource-handler {:path "/"})
|
||||
(swagger/create-swagger-ui-handler
|
||||
{:path "", :url "/api/swagger.json"})
|
||||
(ring/create-default-handler))))
|
||||
|
||||
(defn start []
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@
|
|||
|
||||
#?(:clj
|
||||
;; TODO: optimize for perf
|
||||
;; TODO: ring.middleware.not-modified/wrap-not-modified
|
||||
;; TODO: ring.middleware.head/wrap-head
|
||||
(defn create-resource-handler
|
||||
"A ring handler for serving classpath resources, configured via options:
|
||||
|
||||
|
|
@ -82,19 +84,20 @@
|
|||
| :allow-symlinks? | allow symlinks that lead to paths outside the root classpath directories, defaults to `false`"
|
||||
([]
|
||||
(create-resource-handler nil))
|
||||
([{:keys [parameter root path loader allow-symlinks? index-files]
|
||||
([{:keys [parameter root path loader allow-symlinks? index-files paths]
|
||||
:or {parameter (keyword "")
|
||||
root "public"
|
||||
index-files ["index.html"]}}]
|
||||
index-files ["index.html"]
|
||||
paths (constantly nil)}}]
|
||||
(let [options {:root root, :loader loader, :allow-symlinks? allow-symlinks?}
|
||||
path-size (count path)
|
||||
path-size (inc (count path))
|
||||
create (fn [handler]
|
||||
(fn
|
||||
([request] (handler request))
|
||||
([request respond _] (respond (handler request)))))
|
||||
resource-response (fn [path accept]
|
||||
(if-let [path (accept path)]
|
||||
(if-let [response (response/resource-response path options)]
|
||||
(if-let [response (or (paths path) (response/resource-response path options))]
|
||||
(response/content-type response (mime-type/ext-mime-type path)))))
|
||||
path-or-index-response (fn [path accept]
|
||||
(or (resource-response path accept)
|
||||
|
|
|
|||
|
|
@ -6,4 +6,6 @@
|
|||
:plugins [[lein-parent "0.3.2"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]])
|
||||
:dependencies [[metosin/reitit-ring]
|
||||
[metosin/jsonista]
|
||||
[metosin/ring-swagger-ui]])
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
[meta-merge.core :refer [meta-merge]]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.set :as set]
|
||||
[reitit.coercion :as coercion]))
|
||||
[clojure.string :as str]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.coercion :as coercion]
|
||||
#?@(:clj [
|
||||
[jsonista.core :as j]])))
|
||||
|
||||
(s/def ::id keyword?)
|
||||
(s/def ::no-doc boolean?)
|
||||
|
|
@ -69,7 +73,8 @@
|
|||
"Create a ring handler to emit swagger spec."
|
||||
(fn [{:keys [::r/router ::r/match :request-method]}]
|
||||
(let [{:keys [id] :as swagger} (-> match :result request-method :data :swagger)
|
||||
swagger (set/rename-keys swagger {:id :x-id})
|
||||
swagger (->> (set/rename-keys swagger {:id :x-id})
|
||||
(merge {:swagger "2.0"}))
|
||||
accept-route #(-> % second :swagger :id (= id))
|
||||
transform-endpoint (fn [[method {{:keys [coercion no-doc swagger] :as data} :data}]]
|
||||
(if (and data (not no-doc))
|
||||
|
|
@ -86,3 +91,36 @@
|
|||
(let [paths (->> router (r/routes) (filter accept-route) (map transform-path) (into {}))]
|
||||
{:status 200
|
||||
:body (meta-merge swagger {:paths paths})})))))
|
||||
|
||||
#?(:clj
|
||||
(defn create-swagger-ui-handler
|
||||
"Creates a ring handler which can be used to serve swagger-ui.
|
||||
|
||||
| key | description |
|
||||
| -----------------|-------------|
|
||||
| :parameter | optional name of the wildcard parameter, defaults to unnamed keyword `:`
|
||||
| :root | optional resource root, defaults to `\"swagger-ui\"`
|
||||
| :url | path to swagger endpoint, defaults to `/swagger.json`
|
||||
| :path | optional path to mount the handler to. Works only if mounted outside of a router.
|
||||
| :config | parameters passed to swaggger-ui, keys transformed into camelCase."
|
||||
([]
|
||||
(create-swagger-ui-handler nil))
|
||||
([options]
|
||||
(let [mixed-case (fn [k]
|
||||
(let [[f & rest] (str/split (name k) #"-")]
|
||||
(apply str (str/lower-case f) (map str/capitalize rest))))
|
||||
mixed-case-key (fn [[k v]] [(mixed-case k) v])
|
||||
config-json (fn [{:keys [url config]}] (j/write-value-as-string (merge config {:url url})))
|
||||
conf-js (fn [opts] (str "window.API_CONF = " (config-json opts) ";"))
|
||||
options (as-> options $
|
||||
(update $ :root (fnil identity "swagger-ui"))
|
||||
(update $ :url (fnil identity "/swagger.json"))
|
||||
(update $ :config #(->> % (map mixed-case-key) (into {})))
|
||||
(assoc $ :paths {"conf.js" {:headers {"Content-Type" "application/javascript"}
|
||||
:status 200
|
||||
:body (conf-js $)}
|
||||
"config.json" {:headers {"Content-Type" "application/json"}
|
||||
:status 200
|
||||
:body (config-json $)}}))]
|
||||
(ring/routes
|
||||
(ring/create-resource-handler options))))))
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
[meta-merge "1.0.0"]
|
||||
[ring/ring-core "1.6.3"]
|
||||
[metosin/spec-tools "0.6.2-SNAPSHOT"]
|
||||
[metosin/schema-tools "0.10.2-SNAPSHOT"]]
|
||||
[metosin/schema-tools "0.10.2-SNAPSHOT"]
|
||||
[metosin/ring-swagger-ui "2.2.10"]
|
||||
[metosin/jsonista "0.2.0"]]
|
||||
|
||||
:plugins [[jonase/eastwood "0.2.5"]
|
||||
[lein-doo "0.1.10"]
|
||||
|
|
@ -50,7 +52,8 @@
|
|||
|
||||
[ring "1.6.3"]
|
||||
[metosin/muuntaja "0.5.0"]
|
||||
[metosin/jsonista "0.1.1"]
|
||||
[metosin/jsonista "0.2.0"]
|
||||
[metosin/ring-swagger-ui "2.2.10"]
|
||||
|
||||
[criterium "0.4.4"]
|
||||
[org.clojure/test.check "0.9.0"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue