A fast data-driven routing library for Clojure/Script
1,583
stars
2,065
commits
Clojure
primary language
Sep 8, 2026
updated
A fast data-driven router for Clojure(Script).
Presentations:
Status: stable
Hi! We are Metosin, a consulting company. These libraries have evolved out of the work we do for our clients. We maintain & develop this project, for you, for free. Issues and pull requests welcome! However, if you want more help using the libraries, or want us to build something as cool for you, consider our commercial support.
There is #reitit in Clojurians Slack for discussion & help.
metosin/reitit - all bundledmetosin/reitit-core - the routing coremetosin/reitit-ring - a ring routermetosin/reitit-middleware - common middlewaremetosin/reitit-spec clojure.spec coercionmetosin/reitit-malli malli coercionmetosin/reitit-schema Schema coercionfi.metosin/reitit-openapi OpenAPI apidocs *metosin/reitit-swagger Swagger2 apidocsmetosin/reitit-swagger-ui Integrated Swagger UImetosin/reitit-frontend Tools for frontend routingmetosin/reitit-http http-routing with Interceptorsmetosin/reitit-interceptors - common interceptorsmetosin/reitit-sieppari support for Siepparimetosin/reitit-dev - development utilities... * This is not a typo; the new reitit-openapi was released under the new, verified fi.metosin group. Existing
modules will continue to be released under metosin for compatibility purposes.
reitit-pedestal support for PedestalAll main modules bundled:
[metosin/reitit "0.11.0-rc1"]
Optionally, the parts can be required separately.
Reitit requires Clojure 1.11 and Java 11.
Reitit is tested with the LTS releases Java 11, 17, 21 and 25
(require '[reitit.core :as r])
(def router
(r/router
[["/api/ping" ::ping]
["/api/orders/:id" ::order]]))
(r/match-by-path router "/api/ping")
; #Match{:template "/api/ping"
; :data {:name ::ping}
; :result nil
; :path-params {}
; :path "/api/ping"}
(r/match-by-name router ::order {:id 2})
; #Match{:template "/api/orders/:id",
; :data {:name ::order},
; :result nil,
; :path-params {:id 2},
; :path "/api/orders/2"}
A Ring routing app with input & output coercion using data-specs.
(require '[muuntaja.core :as m])
(require '[reitit.ring :as ring])
(require '[reitit.coercion.spec])
(require '[reitit.ring.coercion :as rrc])
(require '[reitit.ring.middleware.exception :as exception])
(require '[reitit.ring.middleware.muuntaja :as muuntaja])
(require '[reitit.ring.middleware.parameters :as parameters])
(def app
(ring/ring-handler
(ring/router
["/api"
["/math" {:get {:parameters {:query {:x int?, :y int?}}
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x y]} :query} :parameters}]
{:status 200
:body {:total (+ x y)}})}}]]
;; router data affecting all routes
{:data {:coercion reitit.coercion.spec/coercion
:muuntaja m/instance
:middleware [parameters/parameters-middleware ; decoding query & form params
muuntaja/format-middleware ; content negotiation
exception/exception-middleware ; converting exceptions to HTTP responses
rrc/coerce-request-middleware
rrc/coerce-response-middleware]}})))
Valid request:
(-> (app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "2"}})
(update :body slurp))
; {:status 200
; :body "{\"total\":3}"
; :headers {"Content-Type" "application/json; charset=utf-8"}}
Invalid request:
(-> (app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "a"}})
(update :body jsonista.core/read-value))
; {:status 400
; :headers {"Content-Type" "application/json; charset=utf-8"}
; :body {"spec" "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:spec$8974/x :spec$8974/y]), :type :map, :leaf? false})"
; "value" {"x" "1"
; "y" "a"}
; "problems" [{"via" ["spec$8974/y"]
; "path" ["y"]
; "pred" "clojure.core/int?"
; "in" ["y"]
; "val" "a"}]
; "type" "reitit.coercion/request-coercion"
; "coercion" "spec"
; "in" ["request" "query-params"]}}
reitit-ring with coercion, swagger and default middlewarereitit-frontend, the easy wayreitit-frontend with Keechma-style controllersreitit-http with Pedestalreitit-http with SieppariAll examples are in https://github.com/metosin/reitit/tree/master/examples
Check out the full documentation!
Join #reitit channel in Clojurians slack.
Roadmap is mostly written in issues.
Copyright © 2017-2023 Metosin Oy
Distributed under the Eclipse Public License, the same as Clojure.
Clojure
98.5%
A fast data-driven routing library for Clojure/Script
1,583
stars
2,065
commits
Clojure
primary language
Sep 8, 2026
updated
A fast data-driven router for Clojure(Script).
Presentations:
Status: stable
Hi! We are Metosin, a consulting company. These libraries have evolved out of the work we do for our clients. We maintain & develop this project, for you, for free. Issues and pull requests welcome! However, if you want more help using the libraries, or want us to build something as cool for you, consider our commercial support.
There is #reitit in Clojurians Slack for discussion & help.
metosin/reitit - all bundledmetosin/reitit-core - the routing coremetosin/reitit-ring - a ring routermetosin/reitit-middleware - common middlewaremetosin/reitit-spec clojure.spec coercionmetosin/reitit-malli malli coercionmetosin/reitit-schema Schema coercionfi.metosin/reitit-openapi OpenAPI apidocs *metosin/reitit-swagger Swagger2 apidocsmetosin/reitit-swagger-ui Integrated Swagger UImetosin/reitit-frontend Tools for frontend routingmetosin/reitit-http http-routing with Interceptorsmetosin/reitit-interceptors - common interceptorsmetosin/reitit-sieppari support for Siepparimetosin/reitit-dev - development utilities... * This is not a typo; the new reitit-openapi was released under the new, verified fi.metosin group. Existing
modules will continue to be released under metosin for compatibility purposes.
reitit-pedestal support for PedestalAll main modules bundled:
[metosin/reitit "0.11.0-rc1"]
Optionally, the parts can be required separately.
Reitit requires Clojure 1.11 and Java 11.
Reitit is tested with the LTS releases Java 11, 17, 21 and 25
(require '[reitit.core :as r])
(def router
(r/router
[["/api/ping" ::ping]
["/api/orders/:id" ::order]]))
(r/match-by-path router "/api/ping")
; #Match{:template "/api/ping"
; :data {:name ::ping}
; :result nil
; :path-params {}
; :path "/api/ping"}
(r/match-by-name router ::order {:id 2})
; #Match{:template "/api/orders/:id",
; :data {:name ::order},
; :result nil,
; :path-params {:id 2},
; :path "/api/orders/2"}
A Ring routing app with input & output coercion using data-specs.
(require '[muuntaja.core :as m])
(require '[reitit.ring :as ring])
(require '[reitit.coercion.spec])
(require '[reitit.ring.coercion :as rrc])
(require '[reitit.ring.middleware.exception :as exception])
(require '[reitit.ring.middleware.muuntaja :as muuntaja])
(require '[reitit.ring.middleware.parameters :as parameters])
(def app
(ring/ring-handler
(ring/router
["/api"
["/math" {:get {:parameters {:query {:x int?, :y int?}}
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x y]} :query} :parameters}]
{:status 200
:body {:total (+ x y)}})}}]]
;; router data affecting all routes
{:data {:coercion reitit.coercion.spec/coercion
:muuntaja m/instance
:middleware [parameters/parameters-middleware ; decoding query & form params
muuntaja/format-middleware ; content negotiation
exception/exception-middleware ; converting exceptions to HTTP responses
rrc/coerce-request-middleware
rrc/coerce-response-middleware]}})))
Valid request:
(-> (app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "2"}})
(update :body slurp))
; {:status 200
; :body "{\"total\":3}"
; :headers {"Content-Type" "application/json; charset=utf-8"}}
Invalid request:
(-> (app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "a"}})
(update :body jsonista.core/read-value))
; {:status 400
; :headers {"Content-Type" "application/json; charset=utf-8"}
; :body {"spec" "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:spec$8974/x :spec$8974/y]), :type :map, :leaf? false})"
; "value" {"x" "1"
; "y" "a"}
; "problems" [{"via" ["spec$8974/y"]
; "path" ["y"]
; "pred" "clojure.core/int?"
; "in" ["y"]
; "val" "a"}]
; "type" "reitit.coercion/request-coercion"
; "coercion" "spec"
; "in" ["request" "query-params"]}}
reitit-ring with coercion, swagger and default middlewarereitit-frontend, the easy wayreitit-frontend with Keechma-style controllersreitit-http with Pedestalreitit-http with SieppariAll examples are in https://github.com/metosin/reitit/tree/master/examples
Check out the full documentation!
Join #reitit channel in Clojurians slack.
Roadmap is mostly written in issues.
Copyright © 2017-2023 Metosin Oy
Distributed under the Eclipse Public License, the same as Clojure.
(top 30 of 125)
Clojure
98.5%