mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
- don't use no-data no-child routes as examples, they confuse newbies - spell out what route data can be - link to other docs
162 lines
4.3 KiB
Markdown
162 lines
4.3 KiB
Markdown
# Route Syntax
|
|
|
|
Routes are defined as vectors of:
|
|
- path (a string)
|
|
- optional route data: usually a map, but see [Route Data](./route_data.md)
|
|
- any number of 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](../advanced/configuring_routers.md) on how to change this.
|
|
|
|
### Examples
|
|
|
|
Simple route:
|
|
|
|
```clj
|
|
["/ping" {:handler ping}]
|
|
```
|
|
|
|
Two routes with more data:
|
|
|
|
```clj
|
|
[["/ping" {:handler ping
|
|
:cost 300}]
|
|
["/pong" {:handler pong
|
|
:tags #{:game}}]]
|
|
```
|
|
|
|
Routes with path parameters (see also [Coercion](../coercion/coercion.md) and [Ring Coercion](../ring/coercion.md)):
|
|
|
|
```clj
|
|
[["/users/:user-id" {:handler get-user}]
|
|
["/api/:version/ping" {:handler ping-version}]]
|
|
```
|
|
|
|
```clj
|
|
[["/users/{user-id}" {:handler get-user}]
|
|
["/files/file-{number}.pdf" {:handler get-pdf}]]
|
|
```
|
|
|
|
Route with catch-all parameter:
|
|
|
|
```clj
|
|
["/public/*path" {:handler get-file}]
|
|
```
|
|
|
|
```clj
|
|
["/public/{*path}" {:handler get-file}]
|
|
```
|
|
|
|
Nested routes:
|
|
|
|
```clj
|
|
["/api"
|
|
["/admin" {:middleware [::admin]}
|
|
["" {:name ::admin}]
|
|
["/db" {:name ::db}]]
|
|
["/ping" {:name ::ping}]]
|
|
```
|
|
|
|
Same routes flattened:
|
|
|
|
```clj
|
|
[["/api/admin" {:middleware [::admin], :name ::admin}]
|
|
["/api/admin/db" {:middleware [::admin], :name ::db}]
|
|
["/api/ping" {:name ::ping}]]
|
|
```
|
|
|
|
### Encoding
|
|
|
|
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`.
|
|
|
|
### Wildcards
|
|
|
|
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:
|
|
|
|
```clj
|
|
[["/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.
|
|
|
|
```clj
|
|
[["/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:
|
|
|
|
```clj
|
|
[["/files/file-{name}.pdf" {...}] ;; terminator \.
|
|
["/files/file-{name}-{version}.pdf" {...}]] ;; terminator \-
|
|
```
|
|
|
|
### Slash Free Routing
|
|
|
|
```clj
|
|
[["broker.{customer}.{device}.{*data}" {...}]
|
|
["events.{target}.{type}" {...}]]
|
|
```
|
|
|
|
### Generating routes
|
|
|
|
Routes are just data, so it's easy to create them programmatically:
|
|
|
|
```clj
|
|
(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]}}])])
|
|
```
|
|
|
|
```clj
|
|
(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]}}])]
|
|
```
|
|
|
|
### Explicit path-parameter syntax
|
|
|
|
Router options `:syntax` allows the path-parameter syntax to be explicitly 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:
|
|
|
|
```clj
|
|
(-> (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:
|
|
|
|
```clj
|
|
(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"}
|
|
```
|