Search code examples
clojurepedestal

Clojure - combine pedestal routes


How do I combine routes in Pedestal ?

(defroutes api-routes [...])
(defroutes site-routes [...])
(combine-routes api-routes site-routes) ;; should be a valid route as well

Note : This is a similar question as Combining routes in Compojure, but for Pedestal.


Solution

  • It's as easy as

    (def all-routes (concat api-routes site-routes))
    

    The explanation starts from here https://github.com/pedestal/pedestal/blob/master/guides/documentation/service-routing.md#defining-route-tables, it is stated that

    A route table is simply a data structure; in our case, it is a sequence of maps.

    pedestal team calls that sequence of maps route table form as verbose format and they design a terse format of route table which is what we supply to defroute. The defroute then transform our terse format to the verbose format.

    You can check for yourself in the repl

    ;; here we supply a terse route format to defroutes
    > (defroutes routes
      [[["/" {:get home-page}
         ["/hello" {:get hello-world}]]]]) 
    ;;=> #'routes
    
    ;; then we pretty print the verbose route format
    > (pprint routes)
    ;;=>
    ({:path-parts [""],
      :path-params [],
      :interceptors
      [{:name :mavbozo-pedestal.core/home-page,
        :enter
        #object[io.pedestal.interceptor$eval7317$fn__7318$fn__7319 0x95d91f4 "io.pedestal.interceptor$eval7317$fn__7318$fn__7319@95d91f4"],
        :leave nil,
        :error nil}],
      :path "/",
      :method :get,
      :path-re #"/\Q\E",
      :route-name :mavbozo-pedestal.core/home-page}
     {:path-parts ["" "hello"],
      :path-params [],
      :interceptors
      [{:name :mavbozo-pedestal.core/hello-world,
        :enter
        #object[io.pedestal.interceptor$eval7317$fn__7318$fn__7319 0x4a168461 "io.pedestal.interceptor$eval7317$fn__7318$fn__7319@4a168461"],
        :leave nil,
        :error nil}],
      :path "/hello",
      :method :get,
      :path-re #"/\Qhello\E",
      :route-name :mavbozo-pedestal.core/hello-world})
    

    So, because pedestal route is just a sequence of maps, we can easily combine multiple non-overlapping routes with concat.

    That is what I like about one of clojure's principles which pedestal team follows: generic data manipulation which in this case, a verbose formatted route table is just a map--a ordinary clojure's data structure which can be inspected and manipulated with regular clojure.core's data structure manipulation functions such as concat. Even the terse format is also a plain clojure data structure and can easily inspected and manipulated with the same means.