domkm / silk

Routing for Clojure & ClojureScript
222 stars 13 forks source link

silk group & is this a proper way of using ? #5

Closed geraldodev closed 9 years ago

geraldodev commented 9 years ago

Hi,

First, thnx for Silk. I'm trying to use it. I miss a group where I can post doubts.

I've coded the following in order to use silk at client: Any thoughts on this ? Is this a proper way of using silk ?

(def client-routes
  (silk/routes [[:home-page [[]]]
                [:empresa [["empresa"]]]]))

(def client-handlers
  {:home-page (fn [silk-url] (swap! app-state assoc :view :principal))
   :empresa (fn [silk-url] (swap! app-state assoc :view :empresa))})

(defn fn-handler-by-map-key
  "Generates a silk handler function that is capable of looking up the handler-map by :domkm.silk/name and
  call the function returned"
  [handler-map no-match-fn]
  (fn [silk-result]
    (if (nil? silk-result)
      (no-match-fn)
      (let [k (:domkm.silk/name silk-result)
            h (get handler-map k)]
        (if-not h
          (prn "Client handler for key " k " not found")
          (if-not (fn? h)
            (prn "Client handler for key " k " is not a function")
            (h (:domkm.silk/url silk-result))))))))

(def silk-handler (fn-handler-by-map-key client-handlers
                                         #(swap! app-state assoc :view :principal)))

(defn nav-callback
  [{:keys [token]}]
  (silk/arrive client-routes token silk-handler))

(gevents/listen history/history history-event/NAVIGATE
                  (fn [e]
                    (nav-callback {:token (.-token e)
                                   :type (.-type e)
                                   :navigation? (.-isNavigation e)})))
domkm commented 9 years ago

Hi @geraldodev,

Good questions. There isn't a protocol (like HTTP) or any shared abstractions (like Ring) for front-end routing so, unfortunately, most patterns are ad hoc. This is something I'm interested in addressing in the future.

The code you provided seems like a very reasonable way to use Silk. That only thing that immediately stood out is no-match-fn. You might not need to handle a not found case since, if you unmatch (generate) all URLs using the same Silk route table you match against, there's no risk of a link not matching. This is unlike server-side routing where users can request arbitrary URLs.

Cheers, Dom

geraldodev commented 9 years ago

DomKM,

Thanks for the reponse,

"This is unlike server-side routing where users can request arbitrary URLs." The ability of changing the browser's url that the user has leads to the possibility of arbitrary URLs. Does not it ?

I didnt understand "if you unmatch (generate) all URLs using the same Silk route table you match against". Does that imply a different approach handling routes from what I've presented.

Geraldo

domkm commented 9 years ago

If a user changes the browser's URL and requests a new page, that requires server-side routing because the routing occurs on the server, not the browser. When we speak about browser-side routing, the typical pattern is this:

  1. user clicks on a link
  2. prevent event default so we can handle the routing locally
  3. parse the URL via a routing mechanism (like Silk)
  4. handle the change (update app state, etc.)
  5. update window.history or window.location.hash

Unless you are doing something very unusual in the browser, like routing based on user provided text, all routing will be initiated by links that you create. Therefore, if you create the links using a bidirectional routing mechanism like Silk, you can know ahead-of-time that all links are valid and therefore a not found route is unnecessary in the browser. Does that make sense?

geraldodev commented 9 years ago

DomKM,

Yes, totally, but despite being local the user has access to url and can mess up the address.

The bidirectional routing is a bless. I think the arrive/depart abstraction is good but a url-for alias for depart could be good, since is a common name for the function.