mirror of
https://github.com/metosin/reitit.git
synced 2026-02-25 10:32:24 +00:00
A fast data-driven routing library for Clojure/Script
clojureclojurescriptdata-drivenfrontendinterceptorsmetosin-activemiddlewarepedestalringroutingswagger
The motivation for this is adding a new API to a legacy service whose data model has evolved over the years. Maybe we cannot guarantee the presence of all fields that are considered mandatory now. Rather than blowing up when attempting to return legacy entries we may want to disable response validation. However, we do want to ensure *new* entries added to the system are valid, so we do not want to disable request validation. Retain the ability to turn off both request and response validation with a single setting for backwards compatibility. |
||
|---|---|---|
| .clj-kondo | ||
| .github/workflows | ||
| .lsp | ||
| dev-resources | ||
| doc | ||
| examples | ||
| modules | ||
| perf-test/clj/reitit | ||
| scripts | ||
| test | ||
| .gitignore | ||
| book.json | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| Justfile | ||
| LICENSE | ||
| lint.sh | ||
| package-lock.json | ||
| package.json | ||
| project.clj | ||
| README.md | ||
reitit

A fast data-driven router for Clojure(Script).
- Simple data-driven route syntax
- Route conflict resolution
- First-class route data
- Bi-directional routing
- Pluggable coercion (malli, schema & clojure.spec)
- Helpers for ring, http, pedestal & frontend
- Friendly Error Messages
- Extendable
- Modular
- Fast
Presentations:
- Reitit, The Ancient Art of Data-Driven, Clojure/North 2019, video
- Faster and Friendlier Routing with Reitit 0.3.0
- Welcome Reitit 0.2.0!
- Data-Driven Ring with Reitit
- Reitit, Data-Driven Routing with Clojure(Script)
Status: stable
Full Documentation
There is #reitit in Clojurians Slack for discussion & help.
Main Modules
reitit- all bundledreitit-core- the routing corereitit-ring- a ring routerreitit-middleware- common middlewarereitit-specclojure.spec coercionreitit-mallimalli coercionreitit-schemaSchema coercionreitit-swaggerSwagger2 apidocsreitit-swagger-uiIntegrated Swagger UIreitit-frontendTools for frontend routingreitit-httphttp-routing with Interceptorsreitit-interceptors- common interceptorsreitit-siepparisupport for Siepparireitit-dev- development utilities
Extra modules
reitit-pedestalsupport for Pedestal
Latest version
All main modules bundled:
[metosin/reitit "0.7.0-alpha7"]
Optionally, the parts can be required separately.
Quick start
(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"}
Ring example
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.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
rrc/coerce-request-middleware
muuntaja/format-response-middleware
rrc/coerce-response-middleware]}})))
Valid request:
(app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "2"}})
; {:status 200
; :body {:total 3}}
Invalid request:
(app {:request-method :get
:uri "/api/math"
:query-params {:x "1", :y "a"}})
;{:status 400,
; :body {:type :reitit.coercion/request-coercion,
; :coercion :spec,
; :spec "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:$spec20745/x :$spec20745/y]), :type :map, :keys #{:y :x}, :keys/req #{:y :x}})",
; :problems [{:path [:y],
; :pred "clojure.core/int?",
; :val "a",
; :via [:$spec20745/y],
; :in [:y]}],
; :value {:x "1", :y "a"},
; :in [:request :query-params]}}
More examples
reitit-ringwith coercion, swagger and default middlewarereitit-frontend, the easy wayreitit-frontendwith Keechma-style controllersreitit-httpwith Pedestalreitit-httpwith Sieppari
All examples are in https://github.com/metosin/reitit/tree/master/examples
External resources
- Simple web application using Ring/Reitit and Integrant: https://github.com/PrestanceDesign/usermanager-reitit-integrant-example
- A simple Clojure backend using Reitit to serve up a RESTful API: startrek. Technologies include:
- https://www.learnreitit.com/
- Lipas, liikuntapalvelut: https://github.com/lipas-liikuntapaikat/lipas
- Implementation of the Todo-Backend API spec, using Clojure, Ring/Reitit and next-jdbc: https://github.com/PrestanceDesign/todo-backend-clojure-reitit
- Ping CRM, a single page app written in Clojure Ring, Reitit, Integrant and next.jdbc: https://github.com/prestancedesign/clojure-inertia-pingcrm-demo
More info
Check out the full documentation!
Join #reitit channel in Clojurians slack.
Roadmap is mostly written in issues.
Special thanks
- Existing Clojure(Script) routing libs, especially to Ataraxy, Bide, Bidi, calfpath, Compojure, Keechma and Pedestal.
- Compojure-api, Kekkonen, Ring-swagger and Yada and for ideas, coercion & stuff.
- Schema and clojure.spec for the validation part.
- httprouter for ideas and a good library to benchmark against
License
Copyright © 2017-2023 Metosin Oy
Distributed under the Eclipse Public License, the same as Clojure.