mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
Fix paths in swagger.json for endpoints with path parameters
This commit is contained in:
parent
91abf8db51
commit
b7341265e9
2 changed files with 82 additions and 50 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
[meta-merge.core :refer [meta-merge]]
|
[meta-merge.core :refer [meta-merge]]
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
|
[clojure.string :as string]
|
||||||
[reitit.coercion :as coercion]))
|
[reitit.coercion :as coercion]))
|
||||||
|
|
||||||
(s/def ::id (s/or :keyword keyword? :set (s/coll-of keyword? :into #{})))
|
(s/def ::id (s/or :keyword keyword? :set (s/coll-of keyword? :into #{})))
|
||||||
|
|
@ -62,6 +63,21 @@
|
||||||
{:name ::swagger
|
{:name ::swagger
|
||||||
:spec ::spec})
|
:spec ::spec})
|
||||||
|
|
||||||
|
(defn- path->template [path endpoint]
|
||||||
|
(let [path-parameters (filter (fn [{:keys [in]}]
|
||||||
|
(= in "path"))
|
||||||
|
(mapcat (fn [[_ {:keys [parameters]}]]
|
||||||
|
parameters)
|
||||||
|
endpoint))]
|
||||||
|
(loop [{:keys [name] :as path-parameter} (first path-parameters)
|
||||||
|
path-parameters (rest path-parameters)
|
||||||
|
path path]
|
||||||
|
(if path-parameter
|
||||||
|
(recur (first path-parameters)
|
||||||
|
(rest path-parameters)
|
||||||
|
(string/replace path (re-pattern (str ":" name)) (str "{" name "}")))
|
||||||
|
path))))
|
||||||
|
|
||||||
(defn create-swagger-handler []
|
(defn create-swagger-handler []
|
||||||
"Create a ring handler to emit swagger spec. Collects all routes from router which have
|
"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."
|
an intersecting `[:swagger :id]` and which are not marked with `:no-doc` route data."
|
||||||
|
|
@ -83,7 +99,7 @@
|
||||||
(dissoc swagger :id))]))
|
(dissoc swagger :id))]))
|
||||||
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 {}))]
|
||||||
[p endpoint]))]
|
[(path->template p endpoint) endpoint]))]
|
||||||
(if id
|
(if id
|
||||||
(let [paths (->> router (r/routes) (filter accept-route) (map transform-path) (into {}))]
|
(let [paths (->> router (r/routes) (filter accept-route) (map transform-path) (into {}))]
|
||||||
{:status 200
|
{:status 200
|
||||||
|
|
|
||||||
|
|
@ -19,20 +19,24 @@
|
||||||
:handler (swagger/create-swagger-handler)}}]
|
:handler (swagger/create-swagger-handler)}}]
|
||||||
|
|
||||||
["/spec" {:coercion spec/coercion}
|
["/spec" {:coercion spec/coercion}
|
||||||
["/plus"
|
["/plus/:z"
|
||||||
{:get {:summary "plus"
|
{:get {:summary "plus"
|
||||||
:parameters {:query {:x int?, :y int?}}
|
:parameters {:query {:x int?, :y int?}
|
||||||
|
:path {:z int?}}
|
||||||
:responses {200 {:body {:total int?}}}
|
:responses {200 {:body {:total int?}}}
|
||||||
:handler (fn [{{{:keys [x y]} :query} :parameters}]
|
:handler (fn [{{{:keys [x y]} :query
|
||||||
{:status 200, :body {:total (+ x y)}})}}]]
|
{:keys [z]} :path} :parameters}]
|
||||||
|
{:status 200, :body {:total (+ x y z)}})}}]]
|
||||||
|
|
||||||
["/schema" {:coercion schema/coercion}
|
["/schema" {:coercion schema/coercion}
|
||||||
["/plus"
|
["/plus/:z"
|
||||||
{:get {:summary "plus"
|
{:get {:summary "plus"
|
||||||
:parameters {:query {:x Int, :y Int}}
|
:parameters {:query {:x Int, :y Int}
|
||||||
|
:path {:z Int}}
|
||||||
:responses {200 {:body {:total Int}}}
|
:responses {200 {:body {:total Int}}}
|
||||||
:handler (fn [{{{:keys [x y]} :query} :parameters}]
|
:handler (fn [{{{:keys [x y]} :query
|
||||||
{:status 200, :body {:total (+ x y)}})}}]]]
|
{:keys [z]} :path} :parameters}]
|
||||||
|
{:status 200, :body {:total (+ x y z)}})}}]]]
|
||||||
|
|
||||||
{:data {:middleware [swagger/swagger-feature
|
{:data {:middleware [swagger/swagger-feature
|
||||||
rrc/coerce-exceptions-middleware
|
rrc/coerce-exceptions-middleware
|
||||||
|
|
@ -42,16 +46,16 @@
|
||||||
(deftest swagger-test
|
(deftest swagger-test
|
||||||
(testing "endpoints work"
|
(testing "endpoints work"
|
||||||
(testing "spec"
|
(testing "spec"
|
||||||
(is (= {:body {:total 3}, :status 200}
|
(is (= {:body {:total 6}, :status 200}
|
||||||
(app
|
(app
|
||||||
{:request-method :get
|
{:request-method :get
|
||||||
:uri "/api/spec/plus"
|
:uri "/api/spec/plus/3"
|
||||||
:query-params {:x "2", :y "1"}}))))
|
:query-params {:x "2", :y "1"}}))))
|
||||||
(testing "schema"
|
(testing "schema"
|
||||||
(is (= {:body {:total 3}, :status 200}
|
(is (= {:body {:total 6}, :status 200}
|
||||||
(app
|
(app
|
||||||
{:request-method :get
|
{:request-method :get
|
||||||
:uri "/api/schema/plus"
|
:uri "/api/schema/plus/3"
|
||||||
:query-params {:x "2", :y "1"}})))))
|
:query-params {:x "2", :y "1"}})))))
|
||||||
(testing "swagger-spec"
|
(testing "swagger-spec"
|
||||||
(let [spec (:body (app
|
(let [spec (:body (app
|
||||||
|
|
@ -60,7 +64,7 @@
|
||||||
(is (= {:x-id #{::math}
|
(is (= {:x-id #{::math}
|
||||||
:swagger "2.0"
|
:swagger "2.0"
|
||||||
:info {:title "my-api"}
|
:info {:title "my-api"}
|
||||||
:paths {"/api/schema/plus" {:get {:parameters [{:description ""
|
:paths {"/api/schema/plus/{z}" {:get {:parameters [{:description ""
|
||||||
:format "int32"
|
:format "int32"
|
||||||
:in "query"
|
:in "query"
|
||||||
:name "x"
|
:name "x"
|
||||||
|
|
@ -71,7 +75,13 @@
|
||||||
:in "query"
|
:in "query"
|
||||||
:name "y"
|
:name "y"
|
||||||
:required true
|
:required true
|
||||||
:type "integer"}]
|
:type "integer"}
|
||||||
|
{:in "path"
|
||||||
|
:name "z"
|
||||||
|
:description ""
|
||||||
|
:type "integer"
|
||||||
|
:required true
|
||||||
|
:format "int32"}]
|
||||||
:responses {200 {:description ""
|
:responses {200 {:description ""
|
||||||
:schema {:additionalProperties false
|
:schema {:additionalProperties false
|
||||||
:properties {"total" {:format "int32"
|
:properties {"total" {:format "int32"
|
||||||
|
|
@ -79,7 +89,7 @@
|
||||||
:required ["total"]
|
:required ["total"]
|
||||||
:type "object"}}}
|
:type "object"}}}
|
||||||
:summary "plus"}}
|
:summary "plus"}}
|
||||||
"/api/spec/plus" {:get {:parameters [{:description ""
|
"/api/spec/plus/{z}" {:get {:parameters [{:description ""
|
||||||
:format "int64"
|
:format "int64"
|
||||||
:in "query"
|
:in "query"
|
||||||
:name "x"
|
:name "x"
|
||||||
|
|
@ -90,7 +100,13 @@
|
||||||
:in "query"
|
:in "query"
|
||||||
:name "y"
|
:name "y"
|
||||||
:required true
|
:required true
|
||||||
:type "integer"}]
|
:type "integer"}
|
||||||
|
{:in "path"
|
||||||
|
:name "z"
|
||||||
|
:description ""
|
||||||
|
:type "integer"
|
||||||
|
:required true
|
||||||
|
:format "int64"}]
|
||||||
:responses {200 {:description ""
|
:responses {200 {:description ""
|
||||||
:schema {:properties {"total" {:format "int64"
|
:schema {:properties {"total" {:format "int64"
|
||||||
:type "integer"}}
|
:type "integer"}}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue