{"id":13491257,"url":"https://github.com/metosin/reitit","last_synced_at":"2025-05-16T19:02:07.706Z","repository":{"id":37270547,"uuid":"99566414","full_name":"metosin/reitit","owner":"metosin","description":"A fast data-driven routing library for Clojure/Script","archived":false,"fork":false,"pushed_at":"2025-05-05T08:28:43.000Z","size":19794,"stargazers_count":1488,"open_issues_count":146,"forks_count":261,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-05-09T18:52:37.059Z","etag":null,"topics":["clojure","clojurescript","data-driven","frontend","interceptors","metosin-active","middleware","pedestal","ring","routing","swagger"],"latest_commit_sha":null,"homepage":"https://cljdoc.org/d/metosin/reitit/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metosin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-08-07T10:29:40.000Z","updated_at":"2025-05-09T05:20:23.000Z","dependencies_parsed_at":"2023-02-17T07:16:16.909Z","dependency_job_id":"99124ef8-f7e0-4b67-94ad-1157a7881b60","html_url":"https://github.com/metosin/reitit","commit_stats":{"total_commits":1574,"total_committers":131,"mean_commits":12.01526717557252,"dds":0.3576874205844981,"last_synced_commit":"5589328a3cff4051fa272008d8c944ff74563597"},"previous_names":[],"tags_count":65,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Freitit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Freitit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Freitit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Freitit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metosin","download_url":"https://codeload.github.com/metosin/reitit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253357355,"owners_count":21895872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","data-driven","frontend","interceptors","metosin-active","middleware","pedestal","ring","routing","swagger"],"created_at":"2024-07-31T19:00:54.972Z","updated_at":"2025-05-16T19:02:07.628Z","avatar_url":"https://github.com/metosin.png","language":"Clojure","funding_links":[],"categories":["Clojure","Web Framework"],"sub_categories":[],"readme":"# reitit \n\n[![Build Status](https://github.com/metosin/reitit/actions/workflows/testsuite.yml/badge.svg)](https://github.com/metosin/reitit/actions)\n[![cljdoc badge](https://cljdoc.org/badge/metosin/reitit)](https://cljdoc.org/d/metosin/reitit/)\n[![Clojars Project](https://img.shields.io/clojars/v/metosin/reitit.svg)](https://clojars.org/metosin/reitit)\n[![Slack](https://img.shields.io/badge/clojurians-reitit-blue.svg?logo=slack)](https://clojurians.slack.com/messages/reitit/)\n\n\u003cimg src=\"https://github.com/metosin/reitit/blob/master/doc/images/reitit.png?raw=true\" align=\"right\" width=\"200\" /\u003e\nA fast data-driven router for Clojure(Script).\n\n* Simple data-driven [route syntax](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-syntax/)\n* Route [conflict resolution](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-conflicts/)\n* First-class [route data](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/route-data/)\n* Bi-directional routing\n* [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) \u0026 [clojure.spec](https://clojure.org/about/spec))\n* 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/) \u0026 [frontend](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/frontend/basics/)\n* Friendly [Error Messages](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/basics/error-messages/)\n* Extendable\n* Modular\n* [Fast](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/misc/performance)\n\nPresentations:\n* [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)\n* [Faster and Friendlier Routing with Reitit 0.3.0](https://www.metosin.fi/blog/faster-and-friendlier-routing-with-reitit030/)\n* [Welcome Reitit 0.2.0!](https://www.metosin.fi/blog/reitit020/)\n* [Data-Driven Ring with Reitit](https://www.metosin.fi/blog/reitit-ring/)\n* [Reitit, Data-Driven Routing with Clojure(Script)](https://www.metosin.fi/blog/reitit/)\n\n**Status:** [stable](https://github.com/metosin/open-source#project-lifecycle-model)\n\n\u003e Hi! We are [Metosin](https://metosin.fi), a consulting company. These libraries have evolved out of the work we do for our clients.\n\u003e We maintain \u0026 develop this project, for you, for free. Issues and pull requests welcome!\n\u003e 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).\n\n## [Full Documentation](https://cljdoc.org/d/metosin/reitit/CURRENT)\n\nThere is [#reitit](https://clojurians.slack.com/messages/reitit/) in [Clojurians Slack](http://clojurians.net/) for discussion \u0026 help.\n\n## Main Modules\n\n* `metosin/reitit` - all bundled\n* `metosin/reitit-core` - the routing core\n* `metosin/reitit-ring` - a [ring router](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/ring/ring-router/)\n* `metosin/reitit-middleware` - [common middleware](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/ring/default-middleware/)\n* `metosin/reitit-spec` [clojure.spec](https://clojure.org/about/spec) coercion\n* `metosin/reitit-malli` [malli](https://github.com/metosin/malli) coercion\n* `metosin/reitit-schema` [Schema](https://github.com/plumatic/schema) coercion\n* `fi.metosin/reitit-openapi` [OpenAPI](https://www.openapis.org/) apidocs *\n* `metosin/reitit-swagger` [Swagger2](https://swagger.io/) apidocs\n* `metosin/reitit-swagger-ui` Integrated [Swagger UI](https://github.com/swagger-api/swagger-ui)\n* `metosin/reitit-frontend` Tools for [frontend routing]((https://cljdoc.org/d/metosin/reitit/CURRENT/doc/frontend/basics/))\n* `metosin/reitit-http` http-routing with Interceptors\n* `metosin/reitit-interceptors` - [common interceptors](https://cljdoc.org/d/metosin/reitit/CURRENT/doc/http/default-interceptors/)\n* `metosin/reitit-sieppari` support for [Sieppari](https://github.com/metosin/sieppari)\n* `metosin/reitit-dev` - development utilities\n\n... * This is not a typo; the new `reitit-openapi` was released under the new, verified `fi.metosin` group. Existing \nmodules will continue to be released under `metosin` for compatibility purposes.\n\n## Extra modules\n\n* `reitit-pedestal` support for [Pedestal](http://pedestal.io)\n\n## Latest version\n\nAll main modules bundled:\n\n```clj\n[metosin/reitit \"0.8.0\"]\n```\n\nOptionally, the parts can be required separately.\n\nReitit requires Clojure 1.11 and Java 11.\n\nReitit is tested with the LTS releases Java 11, 17 and 21.\n\n## Quick start\n\n```clj\n(require '[reitit.core :as r])\n\n(def router\n  (r/router\n    [[\"/api/ping\" ::ping]\n     [\"/api/orders/:id\" ::order]]))\n\n(r/match-by-path router \"/api/ping\")\n; #Match{:template \"/api/ping\"\n;        :data {:name ::ping}\n;        :result nil\n;        :path-params {}\n;        :path \"/api/ping\"}\n\n(r/match-by-name router ::order {:id 2})\n; #Match{:template \"/api/orders/:id\",\n;        :data {:name ::order},\n;        :result nil,\n;        :path-params {:id 2},\n;        :path \"/api/orders/2\"}\n```\n\n## Ring example\n\nA Ring routing app with input \u0026 output coercion using [data-specs](https://github.com/metosin/spec-tools/blob/master/README.md#data-specs).\n\n```clj\n(require '[muuntaja.core :as m])\n(require '[reitit.ring :as ring])\n(require '[reitit.coercion.spec])\n(require '[reitit.ring.coercion :as rrc])\n(require '[reitit.ring.middleware.muuntaja :as muuntaja])\n(require '[reitit.ring.middleware.parameters :as parameters])\n\n(def app\n  (ring/ring-handler\n    (ring/router\n      [\"/api\"\n       [\"/math\" {:get {:parameters {:query {:x int?, :y int?}}\n                       :responses  {200 {:body {:total int?}}}\n                       :handler    (fn [{{{:keys [x y]} :query} :parameters}]\n                                     {:status 200\n                                      :body   {:total (+ x y)}})}}]]\n      ;; router data affecting all routes\n      {:data {:coercion   reitit.coercion.spec/coercion\n              :muuntaja   m/instance\n              :middleware [parameters/parameters-middleware\n                           rrc/coerce-request-middleware\n                           muuntaja/format-response-middleware\n                           rrc/coerce-response-middleware]}})))\n```\n\nValid request:\n\n```clj\n(app {:request-method :get\n      :uri \"/api/math\"\n      :query-params {:x \"1\", :y \"2\"}})\n; {:status 200\n;  :body {:total 3}}\n```\n\nInvalid request:\n\n```clj\n(app {:request-method :get\n      :uri \"/api/math\"\n      :query-params {:x \"1\", :y \"a\"}})\n;{:status 400,\n; :body {:type :reitit.coercion/request-coercion,\n;        :coercion :spec,\n;        :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}})\",\n;        :problems [{:path [:y],\n;                    :pred \"clojure.core/int?\",\n;                    :val \"a\",\n;                    :via [:$spec20745/y],\n;                    :in [:y]}],\n;        :value {:x \"1\", :y \"a\"},\n;        :in [:request :query-params]}}\n```\n\n## More examples\n\n* [`reitit-ring` with coercion, swagger and default middleware](https://github.com/metosin/reitit/blob/master/examples/ring-malli-swagger/src/example/server.clj)\n* [`reitit-frontend`, the easy way](https://github.com/metosin/reitit/blob/master/examples/frontend/src/frontend/core.cljs)\n* [`reitit-frontend` with Keechma-style controllers](https://github.com/metosin/reitit/blob/master/examples/frontend-controllers/src/frontend/core.cljs)\n* [`reitit-http` with Pedestal](https://github.com/metosin/reitit/blob/master/examples/pedestal/src/example/server.clj)\n* [`reitit-http` with Sieppari](https://github.com/metosin/reitit/blob/master/examples/http/src/example/server.clj)\n\nAll examples are in https://github.com/metosin/reitit/tree/master/examples\n\n## External resources\n* Simple web application using Ring/Reitit and Integrant: https://github.com/PrestanceDesign/usermanager-reitit-integrant-example\n* A simple Clojure backend using Reitit to serve up a RESTful API: [startrek](https://github.com/dharrigan/startrek). Technologies include:\n    * [Donut System](https://github.com/donut-party/system)\n    * [next-jdbc](https://github.com/seancorfield/next-jdbc)\n    * [JUXT Clip](https://github.com/juxt/clip)\n    * [Flyway](https://github.com/flyway/flyway)\n    * [HoneySQL](https://github.com/seancorfield/honeysql)\n    * [Babashka](https://babashka.org)\n* https://www.learnreitit.com/\n* Lipas, liikuntapalvelut: https://github.com/lipas-liikuntapaikat/lipas\n* Implementation of the Todo-Backend API spec, using Clojure, Ring/Reitit and next-jdbc: https://github.com/PrestanceDesign/todo-backend-clojure-reitit\n* Ping CRM, a single page app written in Clojure Ring, Reitit, Integrant and next.jdbc: https://github.com/prestancedesign/clojure-inertia-pingcrm-demo\n\n## More info\n\n[Check out the full documentation!](https://cljdoc.org/d/metosin/reitit/CURRENT/)\n\nJoin [#reitit](https://clojurians.slack.com/messages/reitit/) channel in [Clojurians slack](http://clojurians.net/).\n\nRoadmap is mostly written in [issues](https://github.com/metosin/reitit/issues).\n\n## Special thanks\n\n* Existing Clojure(Script) routing libs, especially to\n[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\n[Pedestal](https://github.com/pedestal/pedestal/tree/master/route).\n* [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 \u0026 stuff.\n* [Schema](https://github.com/plumatic/schema) and [clojure.spec](https://clojure.org/about/spec) for the validation part.\n* [httprouter](https://github.com/julienschmidt/httprouter) for ideas and a good library to benchmark against\n\n## License\n\nCopyright © 2017-2023 [Metosin Oy](http://www.metosin.fi)\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetosin%2Freitit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetosin%2Freitit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetosin%2Freitit/lists"}