Liking cljdoc? Tell your friends :D

Route Data

Route data is the core feature of reitit. Routes can have any map-like data attached to them. This data is interpreted either by the client application or the Router via its :coerce and :compile hooks. Route data format can be defined and validated with clojure.spec enabling a architecture of both adaptive and principled components.

Raw routes can have a non-sequential route argument that is expanded (via router :expand hook) 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
    [["/ping" ::ping]
     ["/pong" identity]
     ["/users" {:get {:roles #{:admin}
                      :handler identity}}]]))

The 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 :user/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"}

Nested route data

For nested route trees, route data is accumulated recursively from root towards leafs using meta-merge. Default behavior for colections 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
    ["/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}}]]


By default, router :expand hook maps to reitit.core/expand function, backed by a reitit.core/Expand protocol. One can provide either a totally different function or add new implementations to that protocol. Expand implementations can be recursive.

Naive example to add direct support for route argument:

  (expand [file options]
      #(slurp file)

  ["/" ( "index.html")])

See router options for all available options.

Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close