diff --git a/CHANGELOG.md b/CHANGELOG.md index 9086fc55..25c79d3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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]) diff --git a/modules/reitit-frontend/src/reitit/frontend/controllers.cljs b/modules/reitit-frontend/src/reitit/frontend/controllers.cljs index 9b11bb5b..bf46a3c7 100644 --- a/modules/reitit-frontend/src/reitit/frontend/controllers.cljs +++ b/modules/reitit-frontend/src/reitit/frontend/controllers.cljs @@ -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 diff --git a/test/cljs/reitit/frontend/controllers_test.cljs b/test/cljs/reitit/frontend/controllers_test.cljs index b0acb600..70fbcd9c 100644 --- a/test/cljs/reitit/frontend/controllers_test.cljs +++ b/test/cljs/reitit/frontend/controllers_test.cljs @@ -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 []))