Terse Syntax
As its name implies, the terse syntax provides a compact approach for
describing routes. When the argument to
expand-routes
is a vector, it will be expanded using the terse syntax.
In essense, the terse syntax is nested maps; the nesting supplies the structure of the path and each nested map contains keyword keys to identify handlers (by method), or string keys to describe further nested paths.
This is all a bit complex and hard to describe, thus the move to table routes.
Unlike the table syntax, any verb can be specified without verb whitelisting.
A route table is a vector of nested vectors. Top-level vector(s) are termed application vectors. Nested vectors are termed route vectors.
The spec terse-routes
defines the terse
table format.
There’s an intermediate step hidden in the terse syntax; the map format is quietly converted into the proper terse format; the map is keyed on path name and the value is a route description, which may define sub-routes. These are flattened into a non-nested sequence of routes. |
Quick Reference
Application Vector Format
-
(Optional) A keyword identifying the application by name
-
(Optional) A URL scheme
-
(Optional) A host name
-
(Optional) A port
-
One or more nested route vectors.
Syntax for expand-routes
(ns myapp.service
(:require [io.pedestal.http.route :as route]))
(def routes
[[:hello-world :http
["/order" {:get `list-orders (1)
:post [:post-without-id `create-order]} (2)
["/:id" (3)
^:interceptors [load-order-from-db]
^:constraints {:id #"[0-9]+"}
{:get `view-order
:put `update-order
:post [:post-by-id `create-order]}]]]])
1 | Pedestal will convert the symbol myapp.service/list-orders to a keyword and use that as the route name |
2 | The route name will be :post-without-id |
3 | Nested routes inherit a path prefix from the containing route; this will match on /order/:id . |
Detailed Reference
Path string
The path string must:
-
Start with a slash ("/")
-
Consist of zero or more path segments separated by slashes.
Each path segment is one of:
-
A string literal
-
A colon (":") followed by a legal Clojure identifier name. This is a path parameter.
-
An asterisk ("*") followed by a legal Clojure identifier name. This is a wildcard path.
When routing a request, a path parameter will match any characters other than a slash. The matched string will be bound to the request by the path parameter name from the route.
For example, using the route /users/:id/orders/:order-id
, the following request URLs would be treated as:
URL | Match? | Path params |
---|---|---|
/users/abcdef/orders |
No |
|
/users/abcdef/orders/12345 |
Yes |
|
/users/123545/orders/From%20Strings |
Yes |
|
All path parameter values are strings.
If you wish to use a wild card route as a fallback route then use the Linear Search Router. Keep in mind that wildcard fallback routes are not recommended since they tend to increase the complexity of handler logic. |
Verb map
The verb map contains verb to handler mappings. Each verb in the verb map defines a route. If a handler is referenced by multiple routes, a route name must be specified. The route name is a keyword which occurs in the first position of an interceptor vector in the verb map.
Unlike the Table Route syntax, custom verbs do not need to be white listed. However, :any is a wildcard verb. During request routing, :any will match all requests.
Handler or Interceptors
The "handler position" be anything that satisfies the IntoInterceptor
protocol. This includes:
-
Function value
-
Symbol
-
Var
-
Map
-
List