Table Syntax

Quick Reference

Table Options

Table routes may include an options map to provide defaults for all routes within; this can either be the first argument to table-routes, or it can be an option map mixed in with the routes (each route is a vector) footnote:[This makes sense in terms of converting a set directly into table routes).

The keys :app-name, :host, :port, and :schema set defaults for routes that do not specify the corresponding value.

The :verbs key may be a set of keywords; these are the keywords allowed for routes within the table. This is typically used when verb smuggling.

The :interceptors option key is a seq of interceptors; these are prepended to any interceptors defined by routes in the table.

Route Vector Formats

  1. Path string

  2. Verb. Typically one of :any, :get, :put, :post, :delete, :patch, :options, :head

  3. Handler or vector of interceptors

  4. (Optional) Route name clause

  5. (Optional) Constraint clause

Syntax for table-routes

(ns myapp.service
  (:require [io.pedestal.http.route.definition.table :as table]))

(def application-routes
  (table/table-routes
    {:host "example.com" :scheme :https}
    [["/user"          :get user-search-form]
     ["/user/:user-id" :get view-user        :constraints {:user-id #"[0-9]+"}]
     ,,,
     ]))

The specs table-options and table-routes define the arguments to table-routes.

Syntax for expand-routes

(ns myapp.service
  (:require [io.pedestal.http.route :as route]))

(def application-routes
  (route/expand-routes
    #{{:host "example.com" :scheme :https}
      ["/user"          :get user-search-form]
      ["/user/:user-id" :get view-user        :constraints {:user-id #"[0-9]+"}]
      ,,,
      }))

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:

  1. A string literal

  2. A colon (":") followed by a legal Clojure identifier name. This is a path parameter.

  3. 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

{:id "abcdef" :order-id "12345"}

/users/123545/orders/From%20Strings

Yes

{:id "123545" :order-id "From Strings"}

All path parameter values are strings.

If you wish to use a wild card route as a fallback route then route order matters. To maintain order during route evaluation, use the Linear Search Router and expand your routes explicitly by passing them to the table-routes function using a vector as the top-level collection instead of a set. Keep in mind that wildcard fallback routes are not recommended since they tend to increase the complexity of handler logic.

HTTP Verb

By default, The verb must be one of the keywords in :any, :get, :put, :post, :delete, :patch, :options, or :head. However, you can override the allowed verbs by including an options map with the keyword :verb in your route definition. The value of :verb is a set of verb keywords you wish to support in the routes. It is through this facility that you can specify custom verbs.

When using custom verbs, you will want to configure your interceptors to support verb smuggling.

Syntax for specifying verbs

(def routes #{{:verbs #{:get :stats :version}}
              ["/" :get (conj common-interceptors `home-page)]
              ["/" :stats (conj common-interceptors `stats)]
              ["/" :version (conj common-interceptors `version)]})
:any is a wildcard verb. During request routing, :any will match all requests for any verb.

Handler or Interceptors

The "handler position" can be anything that satisfies the IntoInterceptor protocol. This includes:

  • Function value

  • Symbol

  • Var

  • Map

  • List (of the above)

The options provided to table-routes may include an :interceptors key; this is a seq of interceptors that is prefixed to any interceptors provided by the route.

Route Name Clause

A route name clause is the keyword :route-name followed by a keyword. Route names must be unique. Route name is required unless route name can be deduced from the handler, or final interceptor.

Constraint Clause

A constraint clause is the keyword :constraints followed by a map.

Note that support for constraints exists today only for backwards compatibility; use of path parameter and query parameter constraints is no longer advised.