Routes are defined as vectors of String path and optional (non-sequential) route argument child routes.
Routes can be wrapped in vectors and lists and nil
routes are ignored.
Paths can have path-parameters (:id
) or catch-all-parameters (*path
). Parameters can also be wrapped in brackets, enabling use of qualified keywords {user/id}
, {*user/path}
. By default, both syntaxes are supported, see configuring routers on how to change this.
Simple route:
["/ping"]
Two routes:
[["/ping"]
["/pong"]]
Routes with route arguments:
[["/ping" ::ping]
["/pong" {:name ::pong}]]
Routes with path parameters:
[["/users/:user-id"]
["/api/:version/ping"]]
[["/users/{user-id}"]
["/files/file-{number}.pdf"]]
Route with catch-all parameter:
["/public/*path"]
["/public/{*path}"]
Nested routes:
["/api"
["/admin" {:middleware [::admin]}
["" ::admin]
["/db" ::db]]
["/ping" ::ping]]
Same routes flattened:
[["/api/admin" {:middleware [::admin], :name ::admin}]
["/api/admin/db" {:middleware [::admin], :name ::db}]
["/api/ping" {:name ::ping}]]
Reitit does not apply any encoding to your paths. If you need that, you must encode them yourself. E.g., /foo bar
should be /foo%20bar
.
Normal path-parameters (:id
) can start anywhere in the path string, but have to end either to slash /
(currently hardcoded) or to an end of path string:
[["/api/:version"]
["/files/file-:number"]
["/user/:user-id/orders"]]
Bracket path-parameters can start and stop anywhere in the path-string, the following character is used as a terminator.
[["/api/{version}"]
["/files/{name}.{extension}"]
["/user/{user-id}/orders"]]
Having multiple terminators after a bracket path-path parameter with identical path prefix will cause a compile-time error at router creation:
[["/files/file-{name}.pdf"] ;; terminator \.
["/files/file-{name}-{version}.pdf"]] ;; terminator \-
[["broker.{customer}.{device}.{*data}"]
["events.{target}.{type}"]]
Routes are just data, so it's easy to create them programmatically:
(defn cqrs-routes [actions]
["/api" {:interceptors [::api ::db]}
(for [[type interceptor] actions
:let [path (str "/" (name interceptor))
method (case type
:query :get
:command :post)]]
[path {method {:interceptors [interceptor]}}])])
(cqrs-routes
[[:query 'get-user]
[:command 'add-user]
[:command 'add-order]])
; ["/api" {:interceptors [::api ::db]}
; (["/get-user" {:get {:interceptors [get-user]}}]
; ["/add-user" {:post {:interceptors [add-user]}}]
; ["/add-order" {:post {:interceptors [add-order]}}])]
Router options :syntax
allows the path-parameter syntax to be explicitely defined. It takes a keyword or set of keywords as a value. Valid values are :colon
and :bracket
. Default value is #{:colon :bracket}
.
With defaults:
(-> (r/router
["http://localhost:8080/api/user/{id}" ::user-by-id])
(r/match-by-path "http://localhost:8080/api/user/123"))
;#Match{:template "http://localhost:8080/api/user/{id}",
; :data {:name :user/user-by-id},
; :result nil,
; :path-params {:id "123", :8080 ":8080"},
; :path "http://localhost:8080/api/user/123"}
Supporting only :bracket
syntax:
(require '[reitit.core :as r])
(-> (r/router
["http://localhost:8080/api/user/{id}" ::user-by-id]
{:syntax :bracket})
(r/match-by-path "http://localhost:8080/api/user/123"))
;#Match{:template "http://localhost:8080/api/user/{id}",
; :data {:name :user/user-by-id},
; :result nil,
; :path-params {:id "123"},
; :path "http://localhost:8080/api/user/123"}
Can you improve this documentation? These fine people already did:
Tommi Reiman, Jon McDuffie, Miikka Koskinen & Matthew DavidsonEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close