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
(r/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"}
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
(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}}]]
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 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")])
See router options for all available options.
Can you improve this documentation? These fine people already did:
Tommi Reiman & Kanwei LiEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close