|
1 | 1 | (ns compojure.api.swagger |
2 | | - (:require [compojure.api.common :refer :all] |
3 | | - [compojure.api.core :refer [GET undocumented]] |
4 | | - [compojure.api.common :refer [extract-parameters]] |
| 2 | + (:require [compojure.api.core :as c] |
| 3 | + [compojure.api.common :as common] |
5 | 4 | [compojure.api.middleware :as mw] |
6 | 5 | [ring.util.http-response :refer [ok]] |
7 | 6 | [ring.swagger.common :as rsc] |
|
13 | 12 | [compojure.api.routes :as routes] |
14 | 13 | [cheshire.core :as cheshire])) |
15 | 14 |
|
16 | | -;; |
17 | | -;; generate schema names |
18 | | -;; |
19 | | - |
20 | 15 | #_(defn ensure-parameter-schema-names [endpoint] |
21 | 16 | (if (get-in endpoint [:parameters :body]) |
22 | 17 | (update-in endpoint [:parameters :body] #(swagger/with-named-sub-schemas % "Body")) |
|
33 | 28 | responses)))) |
34 | 29 | endpoint)) |
35 | 30 |
|
36 | | -;; |
37 | | -;; routes |
38 | | -;; |
| 31 | +(defn base-path [request] |
| 32 | + (let [context (swagger/context request)] |
| 33 | + (if (= "" context) "/" context))) |
| 34 | + |
| 35 | +(defn swagger-spec-path |
| 36 | + [app] |
| 37 | + (some-> app |
| 38 | + routes/get-routes |
| 39 | + routes/route-lookup-table |
| 40 | + ::swagger |
| 41 | + keys |
| 42 | + first)) |
39 | 43 |
|
40 | 44 | (defn transform-operations [swagger] |
41 | 45 | (->> swagger |
42 | 46 | (swagger2/transform-operations routes/non-nil-routes) |
43 | 47 | (swagger2/transform-operations routes/strip-no-doc-endpoints))) |
44 | 48 |
|
45 | | -(defn base-path [request] |
46 | | - (let [context (swagger/context request)] |
47 | | - (if (= "" context) "/" context))) |
48 | | - |
49 | | -;; |
50 | | -;; Public api |
51 | | -;; |
52 | | - |
53 | 49 | (defn swagger-ui [& params] |
54 | | - (undocumented |
| 50 | + (c/undocumented |
55 | 51 | (apply rsui/swagger-ui params))) |
56 | 52 |
|
57 | | -(defn swagger-docs |
58 | | - "Route to serve the swagger api-docs. If the first |
59 | | - parameter is a String, it is used as a url for the |
60 | | - api-docs, otherwise \"/swagger.json\" will be used. |
61 | | - Next Keyword value pairs OR a map for meta-data. |
62 | | - Meta-data can be any valid swagger 2.0 data. Common |
63 | | - case is to introduce API Info and Tags here: |
64 | | -
|
65 | | - {:info {:version \"1.0.0\" |
66 | | - :title \"Sausages\" |
67 | | - :description \"Sausage description\" |
68 | | - :termsOfService \"http://helloreverb.com/terms/\" |
69 | | - :contact {:name \"My API Team\" |
70 | | - |
71 | | - :url \"http://www.metosin.fi\"} |
72 | | - :license {:name: \"Eclipse Public License\" |
73 | | - :url: \"http://www.eclipse.org/legal/epl-v10.html\"}} |
74 | | - :tags [{:name \"sausages\", :description \"Sausage api-set}]}" |
75 | | - [& body] |
| 53 | +(defn swagger-docs [& body] |
76 | 54 | (let [[path body] (if (string? (first body)) |
77 | 55 | [(first body) (rest body)] |
78 | 56 | ["/swagger.json" body]) |
79 | | - [extra-info] (extract-parameters body)] |
80 | | - (GET path request |
| 57 | + [extra-info] (common/extract-parameters body false)] |
| 58 | + (c/GET path request |
81 | 59 | :no-doc true |
82 | 60 | :name ::swagger |
83 | 61 | (let [runtime-info (rsm/get-swagger-data request) |
|
88 | 66 | spec (swagger2/swagger-json swagger options)] |
89 | 67 | (ok spec))))) |
90 | 68 |
|
91 | | -(defn swagger-spec-path [app] |
92 | | - (some-> app |
93 | | - routes/get-routes |
94 | | - routes/route-lookup-table |
95 | | - ::swagger |
96 | | - keys |
97 | | - first)) |
| 69 | +;; |
| 70 | +;; Public api |
| 71 | +;; |
| 72 | + |
| 73 | +(def swagger-defaults {:ui "/", :spec "/swagger.json"}) |
| 74 | + |
| 75 | +(defn swagger-routes |
| 76 | + "Returns routes for swagger-articats (ui & spec). Accepts an options map, with the |
| 77 | + following options: |
| 78 | +
|
| 79 | + **:ui** Uri for the swagger-ui (defaults to \"/\"). |
| 80 | + Setting the value to nil will cause the swagger-ui not to be mounted |
| 81 | +
|
| 82 | + **:spec** Uri for the swagger-spec (defaults to \"/swagger.json\") |
| 83 | + Setting the value to nil will cause the swagger-ui not to be mounted |
| 84 | +
|
| 85 | + **:data** Swagger data in the Ring-Swagger format. |
| 86 | +
|
| 87 | + **:options** |
| 88 | + **:ui** Options to configure the ui |
| 89 | + **:spec** Options to configure the spec. Nada at the moment. |
| 90 | +
|
| 91 | + Example options: |
| 92 | +
|
| 93 | + {:ui \"/api-docs\" |
| 94 | + :spec \"/swagger.json\" |
| 95 | + :options {:ui {:jsonEditor true} |
| 96 | + :spec {}} |
| 97 | + :data {:info {:version \"1.0.0\" |
| 98 | + :title \"Sausages\" |
| 99 | + :description \"Sausage description\" |
| 100 | + :termsOfService \"http://helloreverb.com/terms/\" |
| 101 | + :contact {:name \"My API Team\" |
| 102 | + |
| 103 | + :url \"http://www.metosin.fi\"} |
| 104 | + :license {:name: \"Eclipse Public License\" |
| 105 | + :url: \"http://www.eclipse.org/legal/epl-v10.html\"}} |
| 106 | + :tags [{:name \"sausages\", :description \"Sausage api-set\"}]}}" |
| 107 | + ([] (swagger-routes {})) |
| 108 | + ([options] |
| 109 | + (if options |
| 110 | + (let [{:keys [ui spec data] {ui-options :ui spec-options :spec} :options} (merge swagger-defaults options)] |
| 111 | + (c/routes |
| 112 | + (if ui (apply swagger-ui ui (mapcat identity (merge ui-options (if spec {:swagger-docs spec}))))) |
| 113 | + (if spec (apply swagger-docs spec (mapcat identity data)))))))) |
98 | 114 |
|
99 | 115 | (defn validate |
100 | 116 | "Validates a api. If the api is Swagger-enabled, the swagger-spec |
|
0 commit comments