Skip to content

Commit 4b1ed7e

Browse files
committed
Merge pull request #164 from metosin/ordering
Ordered routes
2 parents fdbbae6 + 2ac78b6 commit 4b1ed7e

File tree

8 files changed

+78
-74
lines changed

8 files changed

+78
-74
lines changed

examples/src/examples/ordered.clj

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,23 @@
11
(ns examples.ordered
2-
(:require [schema.core :as s]
3-
[flatland.ordered.map :as fom]
4-
[compojure.api.sweet :refer :all]
2+
(:require [compojure.api.sweet :refer :all]
53
[ring.util.http-response :refer :all]))
64

7-
;; does not work with AOT
8-
(s/defschema Ordered
9-
(fom/ordered-map
10-
:a s/Str
11-
:b s/Str
12-
:c s/Str
13-
:d s/Str
14-
:e s/Str
15-
:f s/Str
16-
:g s/Str
17-
:h s/Str))
5+
(defroutes* more-ordered-routes
6+
(GET* "/6" [] (ok))
7+
(GET* "/7" [] (ok))
8+
(GET* "/8" [] (ok)))
189

1910
(defroutes* ordered-routes
2011
(context* "/ordered" []
2112
:tags ["ordered"]
22-
(GET* "/" []
23-
:return Ordered
24-
:summary "Ordered data"
25-
(ok
26-
(fom/ordered-map
27-
:a "a"
28-
:b "b"
29-
:c "c"
30-
:d "d"
31-
:e "e"
32-
:f "f"
33-
:g "g"
34-
:h "h")))))
13+
(context* "/a" []
14+
(GET* "/1" [] (ok))
15+
(GET* "/2" [] (ok))
16+
(GET* "/3" [] (ok))
17+
(context* "/b" []
18+
(GET* "/4" [] (ok))
19+
(GET* "/5" [] (ok)))
20+
(context* "/c" []
21+
more-ordered-routes
22+
(GET* "/9" [] (ok))
23+
(GET* "/10" [] (ok))))))

examples/src/examples/thingie.clj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
{:name "primitives", :description "Returning primitive values"}
4242
{:name "context*", :description "context* routes"}
4343
{:name "echo", :description "Echoes data"}
44-
{:name "ordered", :description "Ordered schema"}
44+
{:name "ordered", :description "Ordered routes"}
4545
{:name "file", :description "File upload"}]})
4646

4747
(context* "/math" []
@@ -89,8 +89,6 @@
8989

9090
pizza-routes
9191

92-
#_ordered-routes
93-
9492
(context* "/dates" []
9593
:tags ["dates"]
9694
date-routes)
@@ -196,4 +194,6 @@
196194
:tags ["component"]
197195
(GET* "/example" req
198196
:components [example]
199-
(ok example))))
197+
(ok example)))
198+
199+
ordered-routes)

project.clj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
:profiles {:uberjar {:aot :all
2121
:ring {:handler examples.thingie/app}
2222
:source-paths ["examples/src"]
23-
:dependencies [[http-kit "2.1.19"]
23+
:dependencies [[org.clojure/clojure "1.7.0"]
24+
[http-kit "2.1.19"]
2425
[com.stuartsierra/component "0.2.3"]]}
2526
:dev {:repl-options {:init-ns user}
2627
:plugins [[lein-clojars "0.9.1"]

src/compojure/api/core.clj

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
[compojure.api.routes :as routes]
66
[compojure.core :refer :all]
77
[potemkin :refer [import-vars]]
8-
[ring.swagger.middleware :as rsm]
98
[ring.swagger.common :refer [extract-parameters]]
109
[clojure.walk :as walk]
1110
backtick))
@@ -16,12 +15,11 @@
1615
lookup table via wrap-options. Returned handler retains the original
1716
meta-data."
1817
[handler options]
19-
(let [{:keys [routes lookup] :as meta} (meta handler)]
18+
(let [meta (-> handler meta (assoc :options options))]
2019
(-> handler
21-
(rsm/wrap-swagger-data routes)
2220
(mw/api-middleware options)
23-
(mw/wrap-options {:lookup lookup})
24-
(with-meta (assoc meta :options options)))))
21+
(mw/wrap-options (select-keys meta [:routes :lookup]))
22+
(with-meta meta))))
2523

2624
(defmacro api
2725
"Returns a ring handler wrapped in compojure.api.middleware/api-middlware.

src/compojure/api/routes.clj

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
[cheshire.core :as json]
55
[ring.swagger.swagger2 :as rss]
66
[compojure.api.middleware :as mw]
7-
[clojure.string :as str]))
7+
[clojure.string :as str]
8+
[flatland.ordered.map :as om]))
89

910
(defn- un-quote [s]
1011
(str/replace s #"^\"(.+(?=\"$))\"$" "$1"))
@@ -67,13 +68,20 @@
6768

6869
(defmulti collect-routes identity)
6970

71+
(defn route-vector-to-route-map [v]
72+
{:paths (apply om/ordered-map (apply concat v))})
73+
74+
(defn route-map-to-route-vector [m]
75+
(->> m :paths (apply vector) reverse vec))
76+
7077
(defmacro api-root [& body]
7178
(let [[all-routes body] (collect-routes body)
7279
lookup (route-lookup-table all-routes)
7380
documented-routes (->> all-routes
7481
(rss/transform-operations non-nil-routes)
75-
(rss/transform-operations strip-no-doc-endpoints))]
76-
`(with-meta (routes ~@body) {:routes '~documented-routes
82+
(rss/transform-operations strip-no-doc-endpoints))
83+
route-vector (route-map-to-route-vector documented-routes)]
84+
`(with-meta (routes ~@body) {:routes '~route-vector
7785
:lookup ~lookup})))
7886

7987
(defn path-for*

src/compojure/api/swagger.clj

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
[ring.swagger.middleware :as rsm]
1515
[ring.swagger.core :as swagger]
1616
[ring.swagger.ui]
17+
[flatland.ordered.map :as om]
1718
[ring.swagger.swagger2 :as swagger2]
1819
[schema.core :as s]))
1920

@@ -231,7 +232,7 @@
231232
path-vals
232233
(map create-api-route)
233234
(map attach-meta-data-to-route)
234-
(apply deep-merge {})))
235+
(apply deep-merge (om/ordered-map))))
235236

236237
(defn swagger-info [body]
237238
[{:paths (extract-routes body)} body])
@@ -304,9 +305,12 @@
304305
:name ::swagger
305306
(let [runtime-info# (rsm/get-swagger-data request#)
306307
base-path# {:basePath (base-path request#)}
307-
options# (:ring-swagger (mw/get-options request#))]
308+
options# (:ring-swagger (mw/get-options request#))
309+
routes# (:routes (mw/get-options request#))
310+
paths# (routes/route-vector-to-route-map routes#)]
308311
(ok
309312
(let [swagger# (merge runtime-info#
313+
paths#
310314
base-path#
311315
~extra-info)
312316
result# (swagger2/swagger-json swagger# options#)]
@@ -339,7 +343,8 @@
339343
endpoint is requested. Returns either the (valid) api or throws an
340344
exception."
341345
[api]
342-
(let [{:keys [routes options]} (meta api)]
346+
(let [{:keys [routes options]} (meta api)
347+
routes (routes/route-vector-to-route-map routes)]
343348
(assert (not (nil? routes)) "Api did not contain route definitions.")
344349
(when (swagger-api? api)
345350

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,38 @@
11
(ns compojure.api.swagger-ordering-test
2-
(:require [compojure.api.routes :as routes]
3-
[compojure.api.sweet :refer :all]
2+
(:require [compojure.api.sweet :refer :all]
43
[midje.sweet :refer :all]))
54

6-
;; TODO: order!
7-
#_(facts "with 9+ routes"
5+
(defroutes* more-routes
6+
(GET* "/6" [] identity)
7+
(GET* "/7" [] identity)
8+
(GET* "/8" [] identity))
89

9-
(defapi api
10-
(context "/a" []
11-
(GET* "/1" [] identity)
12-
(GET* "/2" [] identity)
13-
(GET* "/3" [] identity)
14-
(context "/b" []
15-
(GET* "/4" [] identity)
16-
(GET* "/5" [] identity))
17-
(context "/c" []
18-
(GET* "/6" [] identity)
19-
(GET* "/7" [] identity)
20-
(GET* "/8" [] identity)
21-
(GET* "/9" [] identity)
22-
(GET* "/10" [] identity))))
10+
(facts "with 10+ routes"
11+
(let [app (api
12+
(swagger-docs)
13+
(context* "/a" []
14+
(GET* "/1" [] identity)
15+
(GET* "/2" [] identity)
16+
(GET* "/3" [] identity)
17+
(context* "/b" []
18+
(GET* "/4" [] identity)
19+
(GET* "/5" [] identity))
20+
(context* "/c" []
21+
more-routes
22+
(GET* "/9" [] identity)
23+
(GET* "/10" [] identity))))]
2324

2425
(fact "swagger-api order is maintained"
25-
(->> (routes/get-routes)
26+
(->> app
27+
meta
2628
:routes
27-
(map :uri)) => ["/a/1"
28-
"/a/2"
29-
"/a/3"
30-
"/a/b/4"
31-
"/a/b/5"
32-
"/a/c/6"
33-
"/a/c/7"
34-
"/a/c/8"
35-
"/a/c/9"
36-
"/a/c/10"]))
29+
(map first)) => ["/a/1"
30+
"/a/2"
31+
"/a/3"
32+
"/a/b/4"
33+
"/a/b/5"
34+
"/a/c/6"
35+
"/a/c/7"
36+
"/a/c/8"
37+
"/a/c/9"
38+
"/a/c/10"])))

test/compojure/api/sweet_test.clj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
[ring.mock.request :refer :all]
66
[schema.core :as s]
77
[clojure.java.io :as io]
8-
[scjsv.core :as scjsv]))
8+
[scjsv.core :as scjsv]
9+
[compojure.api.routes :as routes]))
910

1011
(def validate
1112
(scjsv/validator (slurp (io/resource "ring/swagger/v2.0_schema.json"))))
@@ -71,7 +72,7 @@
7172
(facts "api documentation"
7273
(fact "details are generated"
7374

74-
(-> app meta :routes)
75+
(-> app meta :routes routes/route-vector-to-route-map)
7576

7677
=> {:paths {"/ping" {:get {}}
7778
"/api/ping" {:get {}}

0 commit comments

Comments
 (0)