:params => :path-params

This commit is contained in:
Tommi Reiman 2018-02-01 16:23:44 +02:00
parent 9f60b2f56d
commit 54b24be28e
15 changed files with 78 additions and 79 deletions

View file

@ -46,14 +46,14 @@ Optionally, the parts can be required separately:
; #Match{:template "/api/ping"
; :data {:name ::ping}
; :result nil
; :params {}
; :path-params {}
; :path "/api/ping"}
(r/match-by-name router ::order {:id 2})
; #Match{:template "/api/orders/:id",
;       :data {:name ::order},
; :result nil,
; :params {:id 2},
; :path-params {:id 2},
; :path "/api/orders/2"}
```

View file

@ -53,14 +53,14 @@ Routing:
; #Match{:template "/api/ping"
; :data {:name ::ping}
; :result nil
; :params {}
; :path-params {}
; :path "/api/ping"}
(r/match-by-path router "/api/orders/1")
; #Match{:template "/api/orders/:id"
; :data {:name ::order-by-id}
; :result nil
; :params {:id "1"}
; :path-params {:id "1"}
; :path "/api/orders/1"}
```
@ -74,14 +74,14 @@ Reverse-routing:
; #Match{:template "/api/ping"
; :data {:name ::ping}
; :result nil
; :params {}
; :path-params {}
; :path "/api/ping"}
(r/match-by-name router ::order-by-id)
; #PartialMatch{:template "/api/orders/:id"
; :data {:name :user/order-by-id}
; :result nil
; :params nil
; :path-params nil
; :required #{:id}}
(r/partial-match? (r/match-by-name router ::order-by-id))
@ -91,7 +91,7 @@ Reverse-routing:
; #Match{:template "/api/orders/:id",
; :data {:name ::order-by-id},
; :result nil,
; :params {:id 2},
; :path-params {:id 2},
; :path "/api/orders/2"}
```
@ -141,6 +141,6 @@ Reverse-routing:
; :get {:handler #object[user$handler]}
; :name ::ping}
; :result #Methods{...}
; :params nil
; :path-params nil
; :path "/api/ping"}
```

View file

@ -35,7 +35,7 @@ Matching a route:
; #Match{:template "/api/ping"
; :data {:name :user/ping}
; :result nil
; :params {}
; :path-params {}
; :path "/api/ping"}
```
@ -46,7 +46,7 @@ If not all path-parameters are set, a `PartialMatch` is returned:
; #PartialMatch{:template "/api/user/:id",
; :data {:name :user/user},
; :result nil,
; :params nil,
; :path-params nil,
; :required #{:id}}
(r/partial-match? (r/match-by-name router ::user))
@ -61,7 +61,7 @@ With provided path-parameters:
; :data {:name :user/user}
; :path "/api/user/1"
; :result nil
; :params {:id "1"}}
; :path-params {:id "1"}}
```
There is also a exception throwing version:

View file

@ -33,5 +33,5 @@ Match provides the route information:
; :data {:name :user/user}
; :path "/api/user/1"
; :result nil
; :params {:id "1"}}
; :path-params {:id "1"}}
```

View file

@ -28,14 +28,14 @@ The expanded route data can be retrieved from a router with `routes` and is retu
; #Match{:template "/ping"
; :data {:name :user/ping}
; :result nil
; :params {}
; :path-params {}
; :path "/ping"}
(r/match-by-name router ::ping)
; #Match{:template "/ping"
; :data {:name :user/ping}
; :result nil
; :params {}
; :path-params {}
; :path "/ping"}
```
@ -92,6 +92,6 @@ By default, `reitit/Expand` protocol is used to expand the route arguments. It e
; #Match{:template "/ping"
; :data {:name :user/ping}
; :result nil
; :params {}
; :path-params {}
; :path "/ping"}
```

View file

@ -37,7 +37,7 @@ Successful coercion:
; :coercion <<:spec>>
; :parameters {:path ::path-params}},
; :result {:path #object[reitit.coercion$request_coercer$]},
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :parameters {:path {:company "metosin", :user-id 123}}
; :path "/metosin/users/123"}
```

View file

@ -19,7 +19,7 @@ Match with the parsed `:params` as Strings:
; #Match{:template "/:company/users/:user-id",
; :data {:name :user/user-view},
; :result nil,
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :path "/metosin/users/123"}
```
@ -69,7 +69,7 @@ A Match:
; :parameters {:path {:company java.lang.String,
; :user-id Int}}},
; :result nil,
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :path "/metosin/users/123"}
```
@ -109,7 +109,7 @@ Routing again:
; :parameters {:path {:company java.lang.String,
; :user-id Int}}},
; :result {:path #object[reitit.coercion$request_coercer$]},
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :path "/metosin/users/123"}
```
@ -165,7 +165,7 @@ Here's an full example for doing routing and coercion with Reitit and Schema:
; :parameters {:path {:company java.lang.String,
; :user-id Int}}},
; :result {:path #object[reitit.coercion$request_coercer$]},
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :parameters {:path {:company "metosin", :user-id 123}}
; :path "/metosin/users/123"}

View file

@ -30,7 +30,7 @@ Successful coercion:
; :parameters {:path {:company string?,
; :user-id int?}}},
; :result {:path #object[reitit.coercion$request_coercer$]},
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :parameters {:path {:company "metosin", :user-id 123}}
; :path "/metosin/users/123"}
```

View file

@ -31,7 +31,7 @@ Successful coercion:
; :parameters {:path {:company java.lang.String,
; :user-id Int}}},
; :result {:path #object[reitit.coercion$request_coercer$]},
; :params {:company "metosin", :user-id "123"},
; :path-params {:company "metosin", :user-id "123"},
; :parameters {:path {:company "metosin", :user-id 123}}
; :path "/metosin/users/123"}
```

View file

@ -157,4 +157,4 @@
If coercion or parameters are not defined, return `nil`"
[match]
(if-let [result (:result match)]
(coerce-request result {:path-params (:params match)})))
(coerce-request result {:path-params (:path-params match)})))

View file

@ -100,7 +100,7 @@
(into [] (keep #(compile-route % opts) routes)))
(defn route-info [route]
(select-keys (impl/create route) [:path :parts :params :result :data]))
(select-keys (impl/create route) [:path :parts :path-params :result :data]))
(defprotocol Router
(router-name [this])
@ -108,13 +108,13 @@
(options [this])
(route-names [this])
(match-by-path [this path])
(match-by-name [this name] [this name params]))
(match-by-name [this name] [this name path-params]))
(defn router? [x]
(satisfies? Router x))
(defrecord Match [template data result params path])
(defrecord PartialMatch [template data result params required])
(defrecord Match [template data result path-params path])
(defrecord PartialMatch [template data result path-params required])
(defn partial-match? [x]
(instance? PartialMatch x))
@ -122,12 +122,12 @@
(defn match-by-name!
([this name]
(match-by-name! this name nil))
([this name params]
(if-let [match (match-by-name this name params)]
([this name path-params]
(if-let [match (match-by-name this name path-params)]
(if-not (partial-match? match)
match
(impl/throw-on-missing-path-params
(:template match) (:required match) params)))))
(:template match) (:required match) path-params)))))
(def default-router-options
{:lookup name-lookup
@ -145,10 +145,10 @@
(let [names (find-names routes opts)
[pl nl] (reduce
(fn [[pl nl] [p {:keys [name] :as data} result]]
(let [{:keys [params] :as route} (impl/create [p data result])
(let [{:keys [path-params] :as route} (impl/create [p data result])
f #(if-let [path (impl/path-for route %)]
(->Match p data result % path)
(->PartialMatch p data result % params))]
(->PartialMatch p data result % path-params))]
[(conj pl route)
(if name (assoc nl name f) nl)]))
[[] {}] routes)
@ -166,16 +166,16 @@
names)
(match-by-path [_ path]
(reduce
(fn [acc ^Route route]
(if-let [params ((:matcher route) path)]
(reduced (->Match (:path route) (:data route) (:result route) params path))))
(fn [_ ^Route route]
(if-let [path-params ((:matcher route) path)]
(reduced (->Match (:path route) (:data route) (:result route) path-params path))))
nil pl))
(match-by-name [_ name]
(if-let [match (impl/fast-get lookup name)]
(match nil)))
(match-by-name [_ name params]
(match-by-name [_ name path-params]
(if-let [match (impl/fast-get lookup name)]
(match params)))))))
(match path-params)))))))
(defn lookup-router
"Creates a lookup-router from resolved routes and optional
@ -213,9 +213,9 @@
(match-by-name [_ name]
(if-let [match (impl/fast-get lookup name)]
(match nil)))
(match-by-name [_ name params]
(match-by-name [_ name path-params]
(if-let [match (impl/fast-get lookup name)]
(match params)))))))
(match path-params)))))))
(defn segment-router
"Creates a special prefix-tree style segment router from resolved routes and optional
@ -226,10 +226,10 @@
(let [names (find-names routes opts)
[pl nl] (reduce
(fn [[pl nl] [p {:keys [name] :as data} result]]
(let [{:keys [params] :as route} (impl/create [p data result])
(let [{:keys [path-params] :as route} (impl/create [p data result])
f #(if-let [path (impl/path-for route %)]
(->Match p data result % path)
(->PartialMatch p data result % params))]
(->PartialMatch p data result % path-params))]
[(segment/insert pl p (->Match p data result nil nil))
(if name (assoc nl name f) nl)]))
[nil {}] routes)
@ -248,14 +248,14 @@
(match-by-path [_ path]
(if-let [match (segment/lookup pl path)]
(-> (:data match)
(assoc :params (:params match))
(assoc :path-params (:path-params match))
(assoc :path path))))
(match-by-name [_ name]
(if-let [match (impl/fast-get lookup name)]
(match nil)))
(match-by-name [_ name params]
(match-by-name [_ name path-params]
(if-let [match (impl/fast-get lookup name)]
(match params)))))))
(match path-params)))))))
(defn single-static-path-router
"Creates a fast router of 1 static route(s) and optional
@ -288,9 +288,9 @@
(match-by-name [_ name]
(if (= n name)
match))
(match-by-name [_ name params]
(match-by-name [_ name path-params]
(if (= n name)
(impl/fast-assoc match :params params)))))))
(impl/fast-assoc match :path-params path-params)))))))
(defn mixed-router
"Creates two routers: [[lookup-router]] or [[single-static-path-router]] for
@ -321,9 +321,9 @@
(match-by-name [_ name]
(or (match-by-name static-router name)
(match-by-name wildcard-router name)))
(match-by-name [_ name params]
(or (match-by-name static-router name params)
(match-by-name wildcard-router name params)))))))
(match-by-name [_ name path-params]
(or (match-by-name static-router name path-params)
(match-by-name wildcard-router name path-params)))))))
(defn router
"Create a [[Router]] from raw route data and optionally an options map.

View file

@ -96,7 +96,7 @@
;; Routing (c) Metosin
;;
(defrecord Route [path matcher parts params data result])
(defrecord Route [path matcher parts path-params data result])
(defn create [[path data result]]
(let [path #?(:clj (.intern ^String path) :cljs path)]
@ -110,8 +110,7 @@
:data data})
(dissoc $ :path-re :path-constraints)
(update $ :path-params set)
(set/rename-keys $ {:path-parts :parts
:path-params :params})
(set/rename-keys $ {:path-parts :parts})
(map->Route $))))
(defn wild-route? [[path]]
@ -128,20 +127,20 @@
(not= s1 s2) false
:else (recur ss1 ss2))))
(defn path-for [^Route route params]
(if-let [required (:params route)]
(if (every? #(contains? params %) required)
(str "/" (str/join \/ (map #(get (or params {}) % %) (:parts route)))))
(defn path-for [^Route route path-params]
(if-let [required (:path-params route)]
(if (every? #(contains? path-params %) required)
(str "/" (str/join \/ (map #(get (or path-params {}) % %) (:parts route)))))
(:path route)))
(defn throw-on-missing-path-params [template required params]
(when-not (every? #(contains? params %) required)
(let [defined (-> params keys set)
(defn throw-on-missing-path-params [template required path-params]
(when-not (every? #(contains? path-params %) required)
(let [defined (-> path-params keys set)
missing (clojure.set/difference required defined)]
(throw
(ex-info
(str "missing path-params for route " template " -> " missing)
{:params params, :required required})))))
{:path-params path-params, :required required})))))
(defn fast-assoc
#?@(:clj [[^clojure.lang.Associative a k v] (.assoc a k v)]

View file

@ -3,23 +3,23 @@
(:require [reitit.impl :as impl]
[clojure.string :as str]))
(defrecord Match [data params])
(defrecord Match [data path-params])
(defprotocol Segment
(-insert [this ps data])
(-lookup [this ps params]))
(-lookup [this ps path-params]))
(extend-protocol Segment
nil
(-insert [_ _ _])
(-lookup [_ _ _]))
(defn- -catch-all [children catch-all params p ps]
(defn- -catch-all [children catch-all path-params p ps]
(if catch-all
(-lookup
(impl/fast-get children catch-all)
nil
(assoc params catch-all (str/join "/" (cons p ps))))))
(assoc path-params catch-all (str/join "/" (cons p ps))))))
(defn- segment
([] (segment {} #{} nil nil))
@ -36,12 +36,12 @@
catch-all (or c catch-all)
children (update children (or w c p) #(-insert (or % (segment)) ps d))]
(segment children wilds catch-all match))))
(-lookup [_ [p & ps] params]
(-lookup [_ [p & ps] path-params]
(if (nil? p)
(if match (assoc match :params params))
(or (-lookup (impl/fast-get children' p) ps params)
(some #(-lookup (impl/fast-get children' %) ps (assoc params % p)) wilds)
(-catch-all children' catch-all params p ps))))))))
(if match (assoc match :path-params path-params))
(or (-lookup (impl/fast-get children' p) ps path-params)
(some #(-lookup (impl/fast-get children' %) ps (assoc path-params % p)) wilds)
(-catch-all children' catch-all path-params p ps))))))))
(defn insert [root path data]
(-insert (or root (segment)) (impl/segments path) (map->Match {:data data})))

View file

@ -62,12 +62,12 @@
([request]
(if-let [match (r/match-by-path router (:uri request))]
(let [method (:request-method request :any)
params (:params match)
path-params (:path-params match)
result (:result match)
handler (or (-> result method :handler)
(-> result :any (:handler default-handler)))
request (cond-> (impl/fast-assoc request ::match match)
(seq params) (impl/fast-assoc :path-params params))
(seq path-params) (impl/fast-assoc :path-params path-params))
response (handler request)]
(if (nil? response)
(default-handler request)
@ -76,12 +76,12 @@
([request respond raise]
(if-let [match (r/match-by-path router (:uri request))]
(let [method (:request-method request :any)
params (:params match)
path-params (:path-params match)
result (:result match)
handler (or (-> result method :handler)
(-> result :any (:handler default-handler)))
request (cond-> (impl/fast-assoc request ::match match)
(seq params) (impl/fast-assoc :path-params params))]
(seq path-params) (impl/fast-assoc :path-params path-params))]
(handler request respond raise))
(default-handler request respond raise))))
{::router router}))))

View file

@ -21,13 +21,13 @@
{:template "/api/ipa/:size"
:data {:name ::beer}
:path "/api/ipa/large"
:params {:size "large"}})
:path-params {:size "large"}})
(r/match-by-path router "/api/ipa/large")))
(is (= (r/map->Match
{:template "/api/ipa/:size"
:data {:name ::beer}
:path "/api/ipa/large"
:params {:size "large"}})
:path-params {:size "large"}})
(r/match-by-name router ::beer {:size "large"})))
(is (= nil (r/match-by-name router "ILLEGAL")))
(is (= [::beer] (r/route-names router)))
@ -37,7 +37,7 @@
{:template "/api/ipa/:size"
:data {:name ::beer}
:required #{:size}
:params nil})
:path-params nil})
(r/match-by-name router ::beer)))
(is (r/partial-match? (r/match-by-name router ::beer)))
(is (thrown-with-msg?
@ -77,13 +77,13 @@
{:template "/api/ipa/large"
:data {:name ::beer}
:path "/api/ipa/large"
:params {}})
:path-params {}})
(r/match-by-path router "/api/ipa/large")))
(is (= (r/map->Match
{:template "/api/ipa/large"
:data {:name ::beer}
:path "/api/ipa/large"
:params {:size "large"}})
:path-params {:size "large"}})
(r/match-by-name router ::beer {:size "large"})))
(is (= nil (r/match-by-name router "ILLEGAL")))
(is (= [::beer] (r/route-names router)))
@ -181,7 +181,7 @@
{:template "/api/user/:id/:sub-id"
:data {:mw [:api], :parameters {:id "String", :sub-id "String"}}
:path "/api/user/1/2"
:params {:id "1", :sub-id "2"}})
:path-params {:id "1", :sub-id "2"}})
(r/match-by-path router "/api/user/1/2"))))))
(deftest conflicting-routes-test