2025-05-23 09:56:01 +00:00
# reitit
2024-04-30 08:58:41 +00:00
2024-04-30 09:00:06 +00:00
[](https://github.com/metosin/reitit/actions)
2024-04-30 08:58:41 +00:00
[](https://cljdoc.org/d/metosin/reitit/)
[](https://clojars.org/metosin/reitit)
[](https://clojurians.slack.com/messages/reitit/)
2019-10-30 14:37:58 +00:00
2024-09-02 10:50:39 +00:00
< img src = "https://github.com/metosin/reitit/blob/master/doc/images/reitit.png?raw=true" align = "right" width = "200" / >
2018-02-11 17:15:25 +00:00
A fast data-driven router for Clojure(Script).
2017-08-07 11:08:39 +00:00
2023-10-03 10:06:23 +00:00
* Simple data-driven [route syntax ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-syntax/ )
* Route [conflict resolution ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-conflicts/ )
* First-class [route data ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-data/ )
2017-10-29 07:29:06 +00:00
* Bi-directional routing
2023-10-03 10:06:23 +00:00
* [Pluggable coercion ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/coercion/coercion-explained ) ([malli](https://github.com/metosin/malli), [schema ](https://github.com/plumatic/schema ) & [clojure.spec ](https://clojure.org/about/spec ))
* Helpers for [ring ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/ring/ring-router ), [http ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/http/interceptors/ ), [pedestal ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/http/pedestal/ ) & [frontend ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/frontend/basics/ )
* Friendly [Error Messages ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/error-messages/ )
2017-08-08 12:31:00 +00:00
* Extendable
2017-11-27 06:02:35 +00:00
* Modular
2023-10-03 10:06:23 +00:00
* [Fast ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/misc/performance )
2017-08-08 12:31:00 +00:00
2019-05-20 11:12:00 +00:00
Presentations:
* [Reitit, The Ancient Art of Data-Driven ](https://www.slideshare.net/mobile/metosin/reitit-clojurenorth-2019-141438093 ), Clojure/North 2019, [video ](https://youtu.be/cSntRGAjPiM )
2019-03-17 12:59:33 +00:00
* [Faster and Friendlier Routing with Reitit 0.3.0 ](https://www.metosin.fi/blog/faster-and-friendlier-routing-with-reitit030/ )
2018-09-04 14:47:52 +00:00
* [Welcome Reitit 0.2.0! ](https://www.metosin.fi/blog/reitit020/ )
2018-05-20 19:46:39 +00:00
* [Data-Driven Ring with Reitit ](https://www.metosin.fi/blog/reitit-ring/ )
2018-09-04 14:58:12 +00:00
* [Reitit, Data-Driven Routing with Clojure(Script) ](https://www.metosin.fi/blog/reitit/ )
2018-05-20 19:46:39 +00:00
2021-10-01 08:03:48 +00:00
**Status:** [stable ](https://github.com/metosin/open-source#project-lifecycle-model )
2024-10-10 07:31:26 +00:00
> Hi! We are [Metosin](https://metosin.fi), 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](https://www.metosin.fi/en/open-source-support).
2023-10-03 10:06:23 +00:00
## [Full Documentation](https://cljdoc.org/d/metosin/reitit/CURRENT)
2018-08-25 12:29:45 +00:00
There is [#reitit ](https://clojurians.slack.com/messages/reitit/ ) in [Clojurians Slack ](http://clojurians.net/ ) for discussion & help.
2018-05-20 19:46:39 +00:00
2018-12-26 13:43:26 +00:00
## Main Modules
2018-05-20 16:51:33 +00:00
2024-05-11 00:30:20 +00:00
* `metosin/reitit` - all bundled
* `metosin/reitit-core` - the routing core
* `metosin/reitit-ring` - a [ring router ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/ring/ring-router/ )
* `metosin/reitit-middleware` - [common middleware ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/ring/default-middleware/ )
* `metosin/reitit-spec` [clojure.spec ](https://clojure.org/about/spec ) coercion
* `metosin/reitit-malli` [malli ](https://github.com/metosin/malli ) coercion
* `metosin/reitit-schema` [Schema ](https://github.com/plumatic/schema ) coercion
* `fi.metosin/reitit-openapi` [OpenAPI ](https://www.openapis.org/ ) apidocs *
* `metosin/reitit-swagger` [Swagger2 ](https://swagger.io/ ) apidocs
* `metosin/reitit-swagger-ui` Integrated [Swagger UI ](https://github.com/swagger-api/swagger-ui )
* `metosin/reitit-frontend` Tools for [frontend routing ]((https://cljdoc.org/d/metosin/reitit/CURRENT/doc/frontend/basics/ ))
* `metosin/reitit-http` http-routing with Interceptors
* `metosin/reitit-interceptors` - [common interceptors ](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/http/default-interceptors/ )
* `metosin/reitit-sieppari` support for [Sieppari ](https://github.com/metosin/sieppari )
* `metosin/reitit-dev` - development utilities
2025-05-23 09:56:01 +00:00
... * This is not a typo; the new `reitit-openapi` was released under the new, verified `fi.metosin` group. Existing
2024-09-02 10:36:03 +00:00
modules will continue to be released under `metosin` for compatibility purposes.
2017-12-27 19:35:37 +00:00
2018-12-26 13:43:26 +00:00
## Extra modules
* `reitit-pedestal` support for [Pedestal ](http://pedestal.io )
2017-08-07 11:08:39 +00:00
## Latest version
2018-12-26 13:43:26 +00:00
All main modules bundled:
2017-11-01 07:29:16 +00:00
2017-11-01 17:03:41 +00:00
```clj
2025-10-24 12:52:47 +00:00
[metosin/reitit "0.9.2-rc1"]
2017-11-01 17:03:41 +00:00
```
2017-11-01 07:29:16 +00:00
2019-03-03 18:54:21 +00:00
Optionally, the parts can be required separately.
2018-12-26 13:43:26 +00:00
2025-03-28 13:54:24 +00:00
Reitit requires Clojure 1.11 and Java 11.
2024-04-30 08:11:25 +00:00
2025-03-28 13:54:24 +00:00
Reitit is tested with the LTS releases Java 11, 17 and 21.
2024-04-19 07:15:45 +00:00
2017-10-30 06:46:20 +00:00
## Quick start
```clj
(require '[reitit.core :as r])
(def router
(r/router
[["/api/ping" ::ping]
2017-10-31 08:27:51 +00:00
["/api/orders/:id" ::order]]))
2017-10-30 06:46:20 +00:00
(r/match-by-path router "/api/ping")
; #Match {:template "/api/ping"
2017-11-18 10:47:16 +00:00
; :data {:name ::ping}
2017-10-30 06:46:20 +00:00
; :result nil
2018-02-01 14:23:44 +00:00
; :path-params {}
2017-10-30 06:46:20 +00:00
; :path "/api/ping"}
2017-10-31 08:27:51 +00:00
(r/match-by-name router ::order {:id 2})
2017-10-30 06:46:20 +00:00
; #Match {:template "/api/orders/:id",
2017-11-18 10:47:16 +00:00
; :data {:name ::order},
2017-10-30 06:46:20 +00:00
; :result nil,
2018-02-01 14:23:44 +00:00
; :path-params {:id 2},
2017-10-30 06:46:20 +00:00
; :path "/api/orders/2"}
```
2017-12-27 19:35:37 +00:00
## Ring example
A Ring routing app with input & output coercion using [data-specs ](https://github.com/metosin/spec-tools/blob/master/README.md#data-specs ).
```clj
2021-04-22 06:27:07 +00:00
(require '[muuntaja.core :as m])
2017-12-27 19:35:37 +00:00
(require '[reitit.ring :as ring])
(require '[reitit.coercion.spec])
2017-12-31 09:29:51 +00:00
(require '[reitit.ring.coercion :as rrc])
2025-05-23 09:56:01 +00:00
(require '[reitit.ring.middleware.exception :as exception])
2021-04-22 06:27:07 +00:00
(require '[reitit.ring.middleware.muuntaja :as muuntaja])
(require '[reitit.ring.middleware.parameters :as parameters])
2017-12-27 19:35:37 +00:00
(def app
(ring/ring-handler
(ring/router
["/api"
2017-12-31 09:29:51 +00:00
["/math" {:get {:parameters {:query {:x int?, :y int?}}
2021-04-22 06:27:07 +00:00
:responses {200 {:body {:total int?}}}
:handler (fn [{{{:keys [x y]} :query} :parameters}]
{:status 200
:body {:total (+ x y)}})}}]]
2020-12-27 18:31:48 +00:00
;; router data affecting all routes
2021-04-22 06:27:07 +00:00
{:data {:coercion reitit.coercion.spec/coercion
:muuntaja m/instance
2025-05-23 09:56:01 +00:00
:middleware [parameters/parameters-middleware ; decoding query & form params
muuntaja/format-middleware ; content negotiation
exception/exception-middleware ; converting exceptions to HTTP responses
2017-12-31 09:29:51 +00:00
rrc/coerce-request-middleware
2021-11-08 23:27:01 +00:00
rrc/coerce-response-middleware]}})))
2017-12-27 19:35:37 +00:00
```
Valid request:
```clj
2025-05-23 09:56:01 +00:00
(-> (app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "2"}})
(update :body slurp))
2017-12-27 19:35:37 +00:00
; {:status 200
2025-05-23 09:56:01 +00:00
; :body "{\"total\":3}"
; :headers {"Content-Type" "application/json; charset=utf-8"}}
2017-12-27 19:35:37 +00:00
```
Invalid request:
```clj
2025-05-23 09:56:01 +00:00
(-> (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"]}}
2018-05-20 18:41:38 +00:00
```
2017-12-27 19:35:37 +00:00
2018-08-31 12:13:33 +00:00
## More examples
2023-05-03 14:00:27 +00:00
* [`reitit-ring` with coercion, swagger and default middleware ](https://github.com/metosin/reitit/blob/master/examples/ring-malli-swagger/src/example/server.clj )
2018-09-03 19:26:25 +00:00
* [`reitit-frontend`, the easy way ](https://github.com/metosin/reitit/blob/master/examples/frontend/src/frontend/core.cljs )
2019-01-07 17:19:14 +00:00
* [`reitit-frontend` with Keechma-style controllers ](https://github.com/metosin/reitit/blob/master/examples/frontend-controllers/src/frontend/core.cljs )
2018-09-03 19:26:25 +00:00
* [`reitit-http` with Pedestal ](https://github.com/metosin/reitit/blob/master/examples/pedestal/src/example/server.clj )
* [`reitit-http` with Sieppari ](https://github.com/metosin/reitit/blob/master/examples/http/src/example/server.clj )
2018-08-31 12:13:33 +00:00
All examples are in https://github.com/metosin/reitit/tree/master/examples
2017-12-27 19:35:37 +00:00
2020-09-18 15:01:22 +00:00
## External resources
* Simple web application using Ring/Reitit and Integrant: https://github.com/PrestanceDesign/usermanager-reitit-integrant-example
2022-12-18 07:09:30 +00:00
* A simple Clojure backend using Reitit to serve up a RESTful API: [startrek ](https://github.com/dharrigan/startrek ). Technologies include:
* [Donut System ](https://github.com/donut-party/system )
* [next-jdbc ](https://github.com/seancorfield/next-jdbc )
* [JUXT Clip ](https://github.com/juxt/clip )
* [Flyway ](https://github.com/flyway/flyway )
* [HoneySQL ](https://github.com/seancorfield/honeysql )
* [Babashka ](https://babashka.org )
2020-09-20 15:00:04 +00:00
* https://www.learnreitit.com/
* Lipas, liikuntapalvelut: https://github.com/lipas-liikuntapaikat/lipas
2020-10-13 21:47:10 +00:00
* Implementation of the Todo-Backend API spec, using Clojure, Ring/Reitit and next-jdbc: https://github.com/PrestanceDesign/todo-backend-clojure-reitit
2021-05-25 21:12:15 +00:00
* Ping CRM, a single page app written in Clojure Ring, Reitit, Integrant and next.jdbc: https://github.com/prestancedesign/clojure-inertia-pingcrm-demo
2020-09-18 15:01:22 +00:00
2017-11-12 19:44:40 +00:00
## More info
2017-08-07 11:08:39 +00:00
2023-10-03 10:06:23 +00:00
[Check out the full documentation! ](https://cljdoc.org/d/metosin/reitit/CURRENT/ )
2017-08-11 04:48:55 +00:00
2017-12-29 10:17:53 +00:00
Join [#reitit ](https://clojurians.slack.com/messages/reitit/ ) channel in [Clojurians slack ](http://clojurians.net/ ).
2017-11-12 19:44:40 +00:00
2017-12-29 10:17:53 +00:00
Roadmap is mostly written in [issues ](https://github.com/metosin/reitit/issues ).
2017-11-12 19:44:40 +00:00
2017-08-08 12:31:00 +00:00
## Special thanks
2019-05-22 16:58:03 +00:00
* Existing Clojure(Script) routing libs, especially to
2019-05-20 17:22:24 +00:00
[Ataraxy ](https://github.com/weavejester/ataraxy ), [Bide ](https://github.com/funcool/bide ), [Bidi ](https://github.com/juxt/bidi ), [calfpath ](https://github.com/ikitommi/calfpath ), [Compojure ](https://github.com/weavejester/compojure ), [Keechma ](https://keechma.com/ ) and
2017-08-09 07:36:57 +00:00
[Pedestal ](https://github.com/pedestal/pedestal/tree/master/route ).
2017-12-29 10:17:53 +00:00
* [Compojure-api ](https://github.com/metosin/compojure-api ), [Kekkonen ](https://github.com/metosin/kekkonen ), [Ring-swagger ](https://github.com/metosin/ring-swagger ) and [Yada ](https://github.com/juxt/yada ) and for ideas, coercion & stuff.
2018-02-11 17:15:25 +00:00
* [Schema ](https://github.com/plumatic/schema ) and [clojure.spec ](https://clojure.org/about/spec ) for the validation part.
2019-03-18 08:52:13 +00:00
* [httprouter ](https://github.com/julienschmidt/httprouter ) for ideas and a good library to benchmark against
2017-09-08 05:29:39 +00:00
2017-08-07 11:08:39 +00:00
## License
2023-01-22 12:24:30 +00:00
Copyright © 2017-2023 [Metosin Oy ](http://www.metosin.fi )
2017-08-07 11:08:39 +00:00
Distributed under the Eclipse Public License, the same as Clojure.