{"id":28205795,"url":"https://github.com/coast-framework/router","last_synced_at":"2025-10-16T10:48:59.423Z","repository":{"id":62431687,"uuid":"199089353","full_name":"coast-framework/router","owner":"coast-framework","description":"Easy clojure routing","archived":false,"fork":false,"pushed_at":"2019-08-17T03:57:41.000Z","size":26,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-26T23:27:22.218Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coast-framework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-26T22:58:13.000Z","updated_at":"2022-01-21T15:26:38.000Z","dependencies_parsed_at":"2022-11-01T20:46:38.084Z","dependency_job_id":null,"html_url":"https://github.com/coast-framework/router","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/coast-framework/router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coast-framework%2Frouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coast-framework%2Frouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coast-framework%2Frouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coast-framework%2Frouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coast-framework","download_url":"https://codeload.github.com/coast-framework/router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coast-framework%2Frouter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279179730,"owners_count":26120526,"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","status":"online","status_checked_at":"2025-10-16T02:00:06.019Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-05-17T10:08:33.512Z","updated_at":"2025-10-16T10:48:59.403Z","avatar_url":"https://github.com/coast-framework.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# router\nEasy clojure routing\n\n## Installation\n\nAdd this to your `deps.edn`\n\n```clojure\ncoast-framework/router {:mvn/version \"1.0.1\"}\n```\n\n## Usage\n\nRequire it like this\n\n```clojure\n(ns your-project\n  (:require [router.core :as router]))\n```\n\nUse it like this\n\n```clojure\n(defn index [request]\n  {:status 200\n   :body \"index\"\n   :headers {\"Content-Type\" \"text/plain\"}})\n\n\n(defn post [request]\n  {:status 200\n   :body \"post\"\n   :headers {\"Content-Type\" \"text/plain\"}})\n\n\n(defn account [request]\n  (let [{:keys [params]} request]\n    {:status 200\n     :body (str \"account with id \" (:id params))\n     :headers {\"Content-Type\" \"text/plain\"}}))\n\n\n(def routes\n  (router/routes\n    [:get \"/\" index :index]\n    [:post \"/posts\" post :post]\n    [:get \"/accounts/:id\" account :account]))\n```\n\n### Middleware\n\nThe router supports per-route ring middleware\n\n```clojure\n(defn mw1 [handler]\n  (fn [request]\n    (handler request)))\n\n(defn mw2 [handler]\n  (fn [request]\n    (handler request)))\n\n(def routes\n  (router/routes\n    [:get \"/\" index]\n    (router/middleware mw1 mw2\n      [:get \"/posts\" post]\n      [:get \"/accounts/:id\" account])))\n```\n\n### Combining Handlers\n\nIn some cases it might make more sense to keep separate apps separate and combine them later\ninstead of defining middleware functions across route vectors.\n\n```clojure\n(defn authenticate [handler]\n  (fn [request]\n    (if (some? (:session request))\n      (handler request)\n      {:status 403 :body \"No\"})))\n\n(def private-routes\n  (router/routes\n    [:get \"/accounts\" account/index]\n    [:get \"/accounts/:id\" account/show]\n    [:post \"/accounts\" account/create]\n    [:put \"/accounts/:id\" account/update]))\n\n(def public-routes\n  (router/routes\n    [:get \"/\" home/index]))\n\n(def private-app (-\u003e (router/app private-routes)\n                     (authenticate)))\n\n(def public-app (router/app public-routes))\n\n(def app (router/apps public-app private-app))\n```\n\n### Prefix\n\nYou can also prefix a set of routes like so\n\n```clojure\n(def api-routes (router/routes\n                 (router/prefix \"/api\"\n                  [:get \"/\" routes.api/index :api/index] ; =\u003e GET /api\n                  [:post \"/\" routes.api/post :api/index]))) ; =\u003e POST /api\n```\n\n\n### Helpers\n\nThe `url-for` helper takes a route name and returns the string for that route\n\n```clojure\n(router/url-for :index) ; =\u003e \"/\"\n(router/url-for :hello) ; =\u003e \"/hello\"\n(router/url-for :account {:id 1}) ;=\u003e \"/accounts/1\"\n```\n\nYou can also add query string parameters AND anchor tags\n\n```clojure\n(router/url-for :account/show {:id 1 :? {:sort \"asc\"} :# \"anchor\"}) ; =\u003e \"/accounts/1?sort=asc#anchor\"\n```\n\nThe `action-for` helper takes a route name and optional args and returns a map for forms.\nThe `put`, `patch` and `delete` in forms are all set under the `_method` key.\n\n```clojure\n(router/action-for :account/create) ; =\u003e {:method :post :action \"/accounts\"}\n(router/action-for :account/update {:id 2}) ; =\u003e {:method :post :action \"/accounts/2\" :_method :put}\n```\n\nThe `redirect-to` helper takes a route name and optional args and\nreturns a ring response map with the `\"Location\"` header set\n\n```clojure\n(router/redirect-to :account/show {:id 1}) ; =\u003e {:status 302 :body \"\" :headers {\"Location\" \"/accounts/1\"}}\n(router/redirect-to :index) ; =\u003e  ; =\u003e {:status 302 :body \"\" :headers {\"Location\" \"/\"}}\n```\n\n## Routes\n\nA route is a vector that must have three items, and an optional name\n\n```clojure\n(defn index [request])\n\n[:get \"/\" index] ; this is a a valid route\n```\n\nThe first item in a route is the request method, which can be one of the following:\n\n- `:get`\n- `:post`\n- `:put`\n- `:patch`\n- `:delete`\n- `:head`\n- `:connect`\n- `:trace`\n\nThe next item is the url with any parameters you define:\n\n```clojure\n\"/\" ; =\u003e responds to localhost/ or localhost\n\n\"/accounts/:id\" ; =\u003e responds to localhost/accounts/1 or localhost/accounts/whatever\n\n\"/accounts/:id/todos\" ; =\u003e responds to localhost/accounts/1/todos\n```\n\nThe last required item is the function that will respond to the request.\nThis function takes one argument, the [ring](https://github.com/ring-clojure/ring) request map:\n\n```clojure\n(defn home [request]\n  {:status 200\n   :body \"home\"\n   :headers {\"content-type\" \"text/plain\"}})\n```\n\nThe final, optional item is a name for `url-for` and `action-for` helpers\n\n```clojure\n(defn hello [request]\n  {:status 200\n   :body (str \"hello \" (get-in request [:params :name]))\n   :headers {\"content-type\" \"text/plain\"}})\n\n[:get ; request-method\n \"/hello/:name\" ; url\n hello ; handler function\n :hello-route] ; optional route name\n\n(router/url-for :hello-route {:name \"sean\"}) ; =\u003e \"/hello/sean\"\n```\n\n## Testing\n\n```sh\ncd router \u0026\u0026 make test\n```\n\n## License\n\nMIT\n\n## Contribution\n\nAny and all issues or pull requests welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoast-framework%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoast-framework%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoast-framework%2Frouter/lists"}