Route data is the key feature of reitit. Routes can have any map-like data attached to them, to be interpreted by the client application, Router or routing components like Middleware or Interceptors.
[["/ping" {:name ::ping}]
 ["/pong" {:handler identity}]
 ["/users" {:get {:roles #{:admin}
                  :handler identity}}]]
Besides map-like data, raw routes can have any non-sequential route argument after the path. This argument is expanded by Router (via :expand option) into route data at router creation time.
By default, Keywords are expanded into :name and functions into :handler keys.
(require '[reitit.core :as r])
(def router
  (r/router
    [["/ping" ::ping]
     ["/pong" identity]
     ["/users" {:get {:roles #{:admin}
                      :handler identity}}]]))
Expanded route data can be retrieved from a router with routes and is returned with match-by-path and match-by-name in case of a route match.
(r/routes router)
; [["/ping" {:name ::ping}]
;  ["/pong" {:handler identity]}
;  ["/users" {:get {:roles #{:admin}
;                   :handler identity}}]]
(r/match-by-path router "/ping")
; #Match{:template "/ping"
;        :data {:name :user/ping}
;        :result nil
;        :path-params {}
;        :path "/ping"}
(r/match-by-name router ::ping)
; #Match{:template "/ping"
;        :data {:name :user/ping}
;        :result nil
;        :path-params {}
;        :path "/ping"}
For nested route trees, route data is accumulated recursively from root towards leafs using meta-merge. Default behavior for collections is :append, but this can be overridden to :prepend, :replace or :displace using the target meta-data.
An example router with nested data:
(def router
  (r/router
    ["/api" {:interceptors [::api]}
     ["/ping" ::ping]
     ["/admin" {:roles #{:admin}}
      ["/users" ::users]
      ["/db" {:interceptors [::db]
              :roles ^:replace #{:db-admin}}]]]))
Resolved route tree:
(r/routes router)
; [["/api/ping" {:interceptors [::api]
;                :name :user/ping}]
;  ["/api/admin/users" {:interceptors [::api]
;                       :roles #{:admin}
;                       :name ::users} nil]
;  ["/api/admin/db" {:interceptors [::api ::db]
;                    :roles #{:db-admin}}]]
Just like fragments in React.js, we can create routing tree fragments by using empty path "". This allows us to add route data without accumulating to path.
Given a route tree:
[["/swagger.json" ::swagger]
 ["/api-docs" ::api-docs]
 ["/api/ping" ::ping]
 ["/api/pong" ::pong]]
Adding :no-doc route data to exclude the first routes from generated Swagger documentation:
[["" {:no-doc true}
  ["/swagger.json" ::swagger]
  ["/api-docs" ::api-docs]]
 ["/api/ping" ::ping]
 ["/api/pong" ::pong]]
Accumulated route data:
(def router
  (r/router
    [["" {:no-doc true}
      ["/swagger.json" ::swagger]
      ["/api-docs" ::api-docs]]
     ["/api/ping" ::ping]
     ["/api/pong" ::pong]]))
     
(r/routes router)
; [["/swagger.json" {:no-doc true, :name ::swagger}]
;  ["/api-docs" {:no-doc true, :name ::api-docs}]
;  ["/api/ping" {:name ::ping}]
;  ["/api/pong" {:name ::pong}]]
Route data can be introduced also via Router option :data:
(def router
  (r/router
    ["/api"
     {:middleware [::api]}
     ["/ping" ::ping]
     ["/pong" ::pong]]
    {:data {:middleware [::session]}}))
Expanded routes:
[["/api/ping" {:middleware [::session ::api], :name ::ping}]
 ["/api/pong" {:middleware [::session ::api], :name ::pong}]]
By default, router :expand option has value r/expand function, backed by a r/Expand protocol. Expansion can be customized either by swapping the :expand implementation or by extending the Protocol. r/Expand implementations can be recursive.
Naive example to add direct support for java.io.File route argument:
(extend-type java.io.File
  r/Expand
  (expand [file options]
    (r/expand
      #(slurp file)
      options)))
(r/router
  ["/" (java.io.File. "index.html")])
Page shared routes has an example of an custom :expand implementation.
Can you improve this documentation? These fine people already did:
Tommi Reiman, tjalkane & Kanwei LiEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs | 
| ← | Move to previous article | 
| → | Move to next article | 
| Ctrl+/ | Jump to the search field |