2017-09-18 05:30:03 +00:00
# Introduction
2017-09-14 13:33:36 +00:00
2018-02-11 17:15:25 +00:00
[Reitit ](https://github.com/metosin/reitit ) is a fast data-driven router for Clojure(Script).
2017-09-14 13:33:36 +00:00
2017-10-29 07:29:06 +00:00
* Simple data-driven [route syntax ](./basics/route_syntax.md )
2018-12-27 14:45:33 +00:00
* Route [conflict resolution ](./basics/route_conflicts.md )
2017-11-18 10:47:16 +00:00
* First-class [route data ](./basics/route_data.md )
2017-10-29 07:29:06 +00:00
* Bi-directional routing
2017-12-27 19:35:37 +00:00
* [Pluggable coercion ](./coercion/coercion.md ) ([schema](https://github.com/plumatic/schema) & [clojure.spec ](https://clojure.org/about/spec ))
2018-12-27 14:45:33 +00:00
* Helpers for [ring ](./ring/ring.md ), [http ](./http/interceptors.md ), [pedestal ](./http/pedestal.md ) & [frontend ](./frontend/basics.md )
2019-05-16 04:13:46 +00:00
* Friendly [Error Messages ](./basics/error_messages.md )
2017-09-14 13:33:36 +00:00
* Extendable
2017-11-27 06:02:35 +00:00
* Modular
2017-11-01 08:17:57 +00:00
* [Fast ](performance.md )
2017-09-14 13:33:36 +00:00
2019-03-03 18:54:21 +00:00
There is [#reitit ](https://clojurians.slack.com/messages/reitit/ ) in [Clojurians Slack ](http://clojurians.net/ ) for discussion & help.
2018-12-27 14:45:33 +00:00
## Main Modules
2018-05-20 16:51:33 +00:00
2018-08-19 19:56:54 +00:00
* `reitit` - all bundled
2018-05-20 16:51:33 +00:00
* `reitit-core` - the routing core
2018-08-25 12:29:45 +00:00
* `reitit-ring` - a [ring router ](./ring/ring.md )
* `reitit-middleware` - [common middleware ](./ring/default_middleware.md ) for `reitit-ring`
2018-05-20 16:51:33 +00:00
* `reitit-spec` [clojure.spec ](https://clojure.org/about/spec ) coercion
* `reitit-schema` [Schema ](https://github.com/plumatic/schema ) coercion
* `reitit-swagger` [Swagger2 ](https://swagger.io/ ) apidocs
* `reitit-swagger-ui` Integrated [Swagger UI ](https://github.com/swagger-api/swagger-ui ).
2018-08-31 07:48:13 +00:00
* `reitit-frontend` Tools for [frontend routing ](frontend/basics.md )
2018-09-07 21:05:59 +00:00
* `reitit-http` http-routing with Pedestal-style Interceptors
2018-09-08 07:57:32 +00:00
* `reitit-interceptors` - [common interceptors ](./http/default_interceptors.md ) for `reitit-http`
2018-09-07 21:05:59 +00:00
* `reitit-sieppari` support for [Sieppari ](https://github.com/metosin/sieppari ) Interceptors
2019-03-03 18:54:21 +00:00
* `reitit-dev` - development utilities
2018-08-19 19:56:54 +00:00
2018-12-27 14:45:33 +00:00
## Extra modules
* `reitit-pedestal` support for [Pedestal ](http://pedestal.io )
2018-08-19 19:56:54 +00:00
## Latest version
All bundled:
2017-09-14 13:33:36 +00:00
2017-09-18 05:30:03 +00:00
```clj
2020-05-27 05:32:38 +00:00
[metosin/reitit "0.5.2"]
2017-09-18 05:30:03 +00:00
```
2019-03-03 18:54:21 +00:00
Optionally, the parts can be required separately.
2017-11-13 05:25:33 +00:00
2017-09-18 05:30:03 +00:00
# Examples
## Simple router
```clj
(require '[reitit.core :as r])
(def router
(r/router
[["/api/ping" ::ping]
["/api/orders/:id" ::order-by-id]]))
```
Routing:
```clj
(r/match-by-path router "/api/ipa")
; nil
(r/match-by-path router "/api/ping")
; #Match {:template "/api/ping"
2017-11-18 10:47:16 +00:00
; :data {:name ::ping}
2017-09-18 05:30:03 +00:00
; :result nil
2018-02-01 14:23:44 +00:00
; :path-params {}
2017-09-18 05:30:03 +00:00
; :path "/api/ping"}
(r/match-by-path router "/api/orders/1")
; #Match {:template "/api/orders/:id"
2017-11-18 10:47:16 +00:00
; :data {:name ::order-by-id}
2017-09-18 05:30:03 +00:00
; :result nil
2018-02-01 14:23:44 +00:00
; :path-params {:id "1"}
2017-09-18 05:30:03 +00:00
; :path "/api/orders/1"}
```
Reverse-routing:
```clj
(r/match-by-name router ::ipa)
; nil
(r/match-by-name router ::ping)
; #Match {:template "/api/ping"
2017-11-18 10:47:16 +00:00
; :data {:name ::ping}
2017-09-18 05:30:03 +00:00
; :result nil
2018-02-01 14:23:44 +00:00
; :path-params {}
2017-09-18 05:30:03 +00:00
; :path "/api/ping"}
(r/match-by-name router ::order-by-id)
; #PartialMatch {:template "/api/orders/:id"
2017-11-18 10:47:16 +00:00
; :data {:name :user/order-by-id}
2017-09-18 05:30:03 +00:00
; :result nil
2018-02-01 14:23:44 +00:00
; :path-params nil
2017-09-18 05:30:03 +00:00
; :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",
2017-11-18 10:47:16 +00:00
; :data {:name ::order-by-id},
2017-09-18 05:30:03 +00:00
; :result nil,
2018-02-01 14:23:44 +00:00
; :path-params {:id 2},
2017-09-18 05:30:03 +00:00
; :path "/api/orders/2"}
```
## Ring-router
Ring-router 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.
```clj
(require '[reitit.ring :as ring])
2018-04-29 08:20:48 +00:00
(defn handler [_]
2017-09-18 05:30:03 +00:00
{: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:
```clj
(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:
```clj
(require '[reitit.core :as r])
(-> app (ring/get-router) (r/match-by-name ::ping))
; #Match {:template "/api/ping"
2017-11-18 10:47:16 +00:00
; :data {:middleware [[#object[user$wrap] :api]]
2017-09-18 05:30:03 +00:00
; :get {:handler #object [user$handler]}
; :name ::ping}
; :result #Methods {...}
2018-02-01 14:23:44 +00:00
; :path-params nil
2017-09-18 05:30:03 +00:00
; :path "/api/ping"}
```