Fork me on GitHub

@yogthos Thanks. Juho is pulling out helper code from our projects into reitit-frontend helper module, minimal helpers to avoid the boilerplate of bootstrapping the routing. What is the api/Router in you example?


ah yeah having a frontend modules is a good call, and we're using Reitit with kee-frame, so that's our implementation for the routing protocol in it


as a side note, I can definitely recommend kee-frame just for the controllers alone, I find it makes routing much cleaner than regular re-frame events


@yogthos What's the best information for kee-frame controllers? We have implemented our own controllers


it's mostly inspired by keechma, the idea is that all the logic for setting up a particular page is managed in the controller, so when you hit a route you can do all the setup in one place


I imagine most people end up implementing an ad hoc version of that for bigger apps


Is there a single controller per page?


yeah it's a controller per route approach


We use controller per "reitit layer", e.g. something like [root-controller users-list-controller user-controller] for /users/1


/users could use [root-controller users-list-controller] and then navigating to user route would only start the new controller (`user-controller`)


Kee-frame does something similar, only from a different angle. Each controller decides how to act on the route, just like keechma. So a controller for retrieving a user list can match on both /users and /users/1. The part about "did already match on /users, so don't have to call it again" is implicit in this case.


I'll try to document this better when the code is finally ready


ah interesting, so this way you can chain them


It makes it really easy to share some common logic between pages


Just a slight correction on kee-frame controllers. They aren't tightly paired with specific routes. They each have a function on the route match. When the route changes the function is run. if it transitions from non-nil to nil, the controller calls it's stop fn. if it transitions from nil to a non nil, it invokes it's start fn with the non nil as params. if it transitions between two different non nil values, it calls stop then start.


I really like that approach because it means that you don't have to duplicate logic across many routes for shared resources.


It seems like controller per layer could accomplish something similar, but the kee-frame approach seems more flexible.


I think the key insight of the kee-frame approach is that controllers are for managing pieces of functionality depending on route, not for orchestrating the whole initialization of a particular route. This means that controllers can be far more declarative.


Both kee-frame and the one we have been using for reitit both mimic the excellent work by @mihaelkonjevic for Keechma. Here’s an example syntax of the one we have been using:

["" {:contollers [:root-controller]}
 ["/orders" {:contollers [:users-controller]}
  ["" {:name ::orders}]
  ["/:id" {:contollers [:user-controller]
           :parameters {:path {:id int?}}
           :name ::order}]]]


reitit flattens the routes so effectively there are two routes:

[["/orders" {:contollers [:root-controller
             :name ::orders}]
 ["/orders/:id" {:contollers [:root-controller
                 :parameters {:path {:id int?}}
                 :name ::order}]]


transitioning from /orders to /orders/1 just calls init on :user-controller. Same gets destroyed if you walk back.


Hey guys, just joined to say thanks for the great library (and great documentation too)!