Reitit is a fast data-driven router for Clojure(Script).
There is #reitit in Clojurians Slack for discussion & help.
reitit - all bundledreitit-core - the routing corereitit-ring - a ring routerreitit-middleware - common middleware for reitit-ringreitit-spec clojure.spec coercionreitit-schema Schema coercionreitit-swagger Swagger2 apidocsreitit-openapi OpenAPI 3 apidocsreitit-swagger-ui Integrated Swagger UI.reitit-frontend Tools for frontend routingreitit-http http-routing with Pedestal-style Interceptorsreitit-interceptors - common interceptors for reitit-httpreitit-sieppari support for Sieppari Interceptorsreitit-dev - development utilitiesreitit-pedestal support for PedestalAll bundled:
[metosin/reitit "0.9.2"]
Optionally, the parts can be required separately.
(require '[reitit.core :as r])
(def router
  (r/router
    [["/api/ping" ::ping]
     ["/api/orders/:id" ::order-by-id]]))
Routing:
(r/match-by-path router "/api/ipa")
; nil
(r/match-by-path router "/api/ping")
; #Match{:template "/api/ping"
;        :data {:name ::ping}
;        :result nil
;        :path-params {}
;        :path "/api/ping"}
(r/match-by-path router "/api/orders/1")
; #Match{:template "/api/orders/:id"
;        :data {:name ::order-by-id}
;        :result nil
;        :path-params {:id "1"}
;        :path "/api/orders/1"}
Reverse-routing:
(r/match-by-name router ::ipa)
; nil
(r/match-by-name router ::ping)
; #Match{:template "/api/ping"
;        :data {:name ::ping}
;        :result nil
;        :path-params {}
;        :path "/api/ping"}
(r/match-by-name router ::order-by-id)
; #PartialMatch{:template "/api/orders/:id"
;               :data {:name :user/order-by-id}
;               :result nil
;               :path-params nil
;               :required #{:id}}
(r/partial-match? (r/match-by-name router ::order-by-id))
; true
(r/match-by-name router ::order-by-id {:id 2})
; #Match{:template "/api/orders/:id",
;        :data {:name ::order-by-id},
;        :result nil,
;        :path-params {:id 2},
;        :path "/api/orders/2"}
A Ring router function adds support for :handler functions, :middleware and routing based on :request-method. It also supports pluggable parameter coercion (clojure.spec), data-driven middleware, route and middleware compilation, dynamic extensions and more.
(require '[reitit.ring :as ring])
(defn handler [_]
  {:status 200, :body "ok"})
(defn wrap [handler id]
  (fn [request]
    (update (handler request) :wrap (fnil conj '()) id)))
(def app
  (ring/ring-handler
    (ring/router
      ["/api" {:middleware [[wrap :api]]}
       ["/ping" {:get handler
                 :name ::ping}]
       ["/admin" {:middleware [[wrap :admin]]}
        ["/users" {:get handler
                   :post handler}]]])))
Routing:
(app {:request-method :get, :uri "/api/admin/users"})
; {:status 200, :body "ok", :wrap (:api :admin)}
(app {:request-method :put, :uri "/api/admin/users"})
; nil
Reverse-routing:
(require '[reitit.core :as r])
(-> app (ring/get-router) (r/match-by-name ::ping))
; #Match{:template "/api/ping"
;        :data {:middleware [[#object[user$wrap] :api]]
;               :get {:handler #object[user$handler]}
;        :name ::ping}
;        :result #Methods{...}
;        :path-params nil
;        :path "/api/ping"}
Can you improve this documentation? These fine people already did:
Tommi Reiman, Juho Teperi, Joel Kaasinen, Miikka Koskinen, bplubell, Zachary Teo, Zaymon & Mic SokoliEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs | 
| ← | Move to previous article | 
| → | Move to next article | 
| Ctrl+/ | Jump to the search field |