Replace controller :params with :identity and :parameters

This commit is contained in:
Juho Teperi 2018-12-04 14:53:23 +02:00
parent c314707afb
commit 36109f142c
3 changed files with 53 additions and 42 deletions

View file

@ -1,3 +1,12 @@
## Unreleased
* Frontend controllers:
* Controller `:params` function has been deprecated
* Controller `:identity` function works the same as `:params`
* New `:parameters` option can be used to declare which parameters
controller is interested in, as data, which should cover most
use cases: `{:start start-fn, :parameters {:path [:foo-id]}}`
## 0.2.13 (2019-01-26)
* Don't throw `StringIndexOutOfBoundsException` with empty path lookup on wildcard paths, fixes [#209](https://github.com/metosin/reitit/issues/209)
@ -25,7 +34,7 @@
* new options `:inject-match?` and `:inject-router?` on `reitit.http/ring-handler` and `reitit.http/routing-interceptor` to optionally not to inject `Router` and `Match` into the request. See [performance guide](https://metosin.github.io/reitit/performance.html#faster!) for details.
### dependencies
### dependencies
* updated:
@ -250,7 +259,7 @@
* Swagger enchancements
* Better spec coercion via `st/coerce` using spec walking & inference: many simple specs (core predicates, `spec-tools.core/spec`, `s/and`, `s/or`, `s/coll-of`, `s/keys`, `s/map-of`, `s/nillable` and `s/every`) can be transformed without needing spec to be wrapped. Fallbacks to old conformed based approach.
* [example app](https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj).
* updated deps:
```clj
@ -396,7 +405,7 @@ Sample apps demonstraing the current status of `reitit`:
* when Keywords are used in place of middleware / interceptor, a lookup is done into Router option `::middleware/registry` (or `::interceptor/registry`) with the key. Fails fast with missing registry entries.
* fixes [#32](https://github.com/metosin/reitit/issues/32).
* full documentation [here](https://metosin.github.io/reitit/ring/middleware_registry.html).
```clj
(require '[reitit.ring :as ring])
(require '[reitit.middleware :as middleware])

View file

@ -4,38 +4,41 @@
(defn- pad-same-length [a b]
(concat a (take (- (count b) (count a)) (repeat nil))))
(defn get-params
"Get controller parameters given match. If controller provides :params
function that will be called with the match. Default is nil."
[controller match]
(if-let [f (:params controller)]
(f match)))
(defn get-identity
"Get controller identity given controller and match.
(def static
"Static params means that the identity of controller
doesn't not depend on Match, i.e. any parameters.
To select interesting properties from Match :parameters option can be used.
Resulting value is map of param-type => param => value.
This is same as just not defining :params."
nil)
For other uses, :identity option can be used to provide function from
Match to identity.
(defn parameters
"Given map of parameter-type => list of keys,
returns function taking Match and returning
value containing given parameter types and their
keys.
Default value is nil, i.e. controller identity doesn't depend on Match."
[{:keys [identity parameters params]} match]
(assert (not (and identity parameters))
"Use either :identity or :parameters for controller, not both.")
(when params
(js/console.warn "Controller :params is deprecated. Replace with :identity or :parameters option."))
(cond
parameters
(into {} (for [[param-type ks] parameters]
[param-type (select-keys (get (:parameters match) param-type) ks)]))
The resulting function can be used for :params."
[p]
(fn [match]
(into {} (for [[param-type ks] p]
[param-type (select-keys (get (:parameters match) param-type) ks)]))))
identity
(identity match)
;; Support deprecated :params for transition period. Can be removed later.
params
(params match)
:else nil))
(defn apply-controller
"Run side-effects (:start or :stop) for controller.
The side-effect function is called with controller params."
[controller method]
(when-let [f (get controller method)]
(f (::params controller))))
(f (::identity controller))))
(defn apply-controllers
"Applies changes between current controllers and
@ -43,7 +46,7 @@
identity has changed."
[old-controllers new-match]
(let [new-controllers (mapv (fn [controller]
(assoc controller ::params (get-params controller new-match)))
(assoc controller ::identity (get-identity controller new-match)))
(:controllers (:data new-match)))
changed-controllers (->> (map (fn [old new]
;; different controllers, or params changed

View file

@ -15,15 +15,15 @@
:stop (fn [_] (swap! log conj :stop-2))}
controller-3 {:start (fn [{:keys [foo]}] (swap! log conj [:start-3 foo]))
:stop (fn [{:keys [foo]}] (swap! log conj [:stop-3 foo]))
:params (fn [match]
{:foo (-> match :parameters :path :foo)})}]
:identity (fn [match]
{:foo (-> match :parameters :path :foo)})}]
(testing "single controller started"
(swap! controller-state rfc/apply-controllers
{:data {:controllers [controller-1]}})
(is (= [:start-1] @log))
(is (= [(assoc controller-1 ::rfc/params nil)] @controller-state))
(is (= [(assoc controller-1 ::rfc/identity nil)] @controller-state))
(reset! log []))
(testing "second controller started"
@ -31,8 +31,8 @@
{:data {:controllers [controller-1 controller-2]}})
(is (= [:start-2] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-2 ::rfc/params nil)]
(is (= [(assoc controller-1 ::rfc/identity nil)
(assoc controller-2 ::rfc/identity nil)]
@controller-state))
(reset! log []))
@ -42,8 +42,8 @@
:parameters {:path {:foo 5}}})
(is (= [:stop-2 [:start-3 5]] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-3 ::rfc/params {:foo 5})]
(is (= [(assoc controller-1 ::rfc/identity nil)
(assoc controller-3 ::rfc/identity {:foo 5})]
@controller-state))
(reset! log []))
@ -53,8 +53,8 @@
:parameters {:path {:foo 1}}})
(is (= [[:stop-3 5] [:start-3 1]] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-3 ::rfc/params {:foo 1})]
(is (= [(assoc controller-1 ::rfc/identity nil)
(assoc controller-3 ::rfc/identity {:foo 1})]
@controller-state))
(reset! log []))
@ -70,11 +70,10 @@
(let [log (atom [])
controller-state (atom [])
static {:start (fn [params] (swap! log conj [:start-static]))
:stop (fn [params] (swap! log conj [:stop-static]))
:params rfc/static}
:stop (fn [params] (swap! log conj [:stop-static]))}
controller {:start (fn [params] (swap! log conj [:start params]))
:stop (fn [params] (swap! log conj [:stop params]))
:params (rfc/parameters {:path [:foo]})}]
:parameters {:path [:foo]}}]
(testing "init"
(swap! controller-state rfc/apply-controllers
@ -83,8 +82,8 @@
(is (= [[:start-static]
[:start {:path {:foo 1}}]] @log))
(is (= [(assoc static ::rfc/params nil)
(assoc controller ::rfc/params {:path {:foo 1}})]
(is (= [(assoc static ::rfc/identity nil)
(assoc controller ::rfc/identity {:path {:foo 1}})]
@controller-state))
(reset! log []))
@ -95,8 +94,8 @@
(is (= [[:stop {:path {:foo 1}}]
[:start {:path {:foo 5}}]] @log))
(is (= [(assoc static ::rfc/params nil)
(assoc controller ::rfc/params {:path {:foo 5}})]
(is (= [(assoc static ::rfc/identity nil)
(assoc controller ::rfc/identity {:path {:foo 5}})]
@controller-state))
(reset! log []))