{"id":20390521,"url":"https://github.com/swlkr/trail","last_synced_at":"2025-04-12T11:21:48.643Z","repository":{"id":57714074,"uuid":"104970808","full_name":"swlkr/trail","owner":"swlkr","description":"A clojure routing library for ring","archived":false,"fork":false,"pushed_at":"2018-02-08T16:16:09.000Z","size":46,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-01T21:43:20.714Z","etag":null,"topics":["clojure","http","ring","routing","trail"],"latest_commit_sha":null,"homepage":"","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/swlkr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2017-09-27T04:10:07.000Z","updated_at":"2019-08-21T21:41:56.000Z","dependencies_parsed_at":"2022-09-26T21:31:09.896Z","dependency_job_id":null,"html_url":"https://github.com/swlkr/trail","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlkr%2Ftrail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlkr%2Ftrail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlkr%2Ftrail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlkr%2Ftrail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swlkr","download_url":"https://codeload.github.com/swlkr/trail/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248558132,"owners_count":21124223,"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","http","ring","routing","trail"],"created_at":"2024-11-15T03:25:34.532Z","updated_at":"2025-04-12T11:21:48.623Z","avatar_url":"https://github.com/swlkr.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trail\n\nRing routing library\n\n## Install\n\n[Looking for v1? Look no further my friend!](https://github.com/swlkr/trail/tree/1.13.0)\n\nAdd this to your `project.clj`\n\n```clojure\n[trail \"2.1.0\"]\n```\n\n## Usage\n\n```clojure\n(ns your-app.core\n  (require [trail.core :as trail]))\n```\n\nThese are the routes\n\n```clojure\n(def routes [\n  [:get    \"/items\"           items/index]\n  [:get    \"/items/:id\"       items/show]\n  [:get    \"/items/:id/fresh\" items/fresh]\n  [:get    \"/items/:id/edit\"  items/edit]\n  [:post   \"/items\"           items/create]\n  [:put    \"/items/:id\"       items/change]\n  [:delete \"/items/:id\"       items/delete]\n])\n```\n\nAnd you can write your routes as data if you wanted to.\nOr there are some functions if you prefer parens\n\n```clojure\n(def routes\n  (-\u003e (trail/get    \"/items\"           items/index)\n      (trail/get    \"/items/:id\"       items/show)\n      (trail/get    \"/items/:id/fresh\" items/fresh)\n      (trail/get    \"/items/:id/edit\"  items/edit)\n      (trail/post   \"/items\"           items/create)\n      (trail/put    \"/items/:id\"       items/change)\n      (trail/delete \"/items/:id\"       items/delete)))\n```\n\nThere's also a function that turns your route into a ring\nhandler function\n\n`(trail/match-routes your-route-map)`\n\nHere's a more complete example\n\n```clojure\n(ns your-app.core\n  (require [trail.core :as trail]\n           [org.httpkit.server :as server]\n           [ring.middleware.defaults :as ring-defaults]\n           [your-app.controllers.items :as items]))\n\n(def routes\n  (-\u003e (trail/get    \"/items\"           items/index)\n      (trail/get    \"/items/:id\"       items/show)\n      (trail/get    \"/items/:id/fresh\" items/fresh)\n      (trail/get    \"/items/:id/edit\"  items/edit)\n      (trail/post   \"/items\"           items/create)\n      (trail/put    \"/items/:id\"       items/change)\n      (trail/delete \"/items/:id\"       items/delete)))\n\n(def app\n  (-\u003e (trail/match-routes routes) ; it's this one here\n      (ring-defaults/wrap-defaults site-defaults)))\n\n(server/run-server app {:port 1337})\n```\n\nThe last thing this library has that other routing\nlibraries do not is the concept of a `resource`\nshamelessly stolen from rails routing\n\nSo instead of this\n\n```clojure\n(ns your-app.core\n  (require [trail.core :as trail]\n           [your-app.controllers.items :as items]))\n\n(def routes\n  (-\u003e (trail/get    \"/items\"           items/index)\n      (trail/get    \"/items/:id\"       items/show)\n      (trail/get    \"/items/:id/fresh\" items/fresh)\n      (trail/get    \"/items/:id/edit\"  items/edit)\n      (trail/post   \"/items\"           items/create)\n      (trail/put    \"/items/:id\"       items/change)\n      (trail/delete \"/items/:id\"       items/delete)))\n```\n\nYou can do this\n\n```clojure\n(ns your-app.core\n  (require [trail.core :as trail]\n           [your-app.controllers.items :as items]))\n\n(def routes\n  (-\u003e (trail/resource :items)))\n```\n\nAnd you can do this\n\n```clojure\n(ns your-app.core\n  (:require [trail.core :as trail]\n            [your-app.controllers.posts :as posts]\n            [your-app.controllers.tags :as tags]))\n\n(def routes\n  (-\u003e (trail/resource :posts :tags))\n\n; this gives you\n;\n; GET \"/posts/:post-id/tags\" =\u003e tags/index\n; GET \"/posts/:post-id/tags/:id\" =\u003e tags/show\n; GET \"/posts/:post-id/tags/new\" =\u003e tags/fresh\n; GET \"/posts/:post-id/tags/:id/edit\" =\u003e tags/edit\n; POST \"/posts/:post-id/tags\" =\u003e tags/create\n; PUT \"/posts/:post-id/tags/:id\" =\u003e tags/change\n; DELETE \"/posts/:post-id/tags/:id\" =\u003e tags/delete\n```\n\nDon't want all of the routes a resource gives you?\n\n```clojure\n(def routes\n (-\u003e (trail/resource :posts :only [:index :show])))\n \n; =\u003e\n[\n [:get \"/posts\"     posts/index]\n [:get \"/posts/:id\" posts/show]\n]\n```\n\nWant all of the routes except certain ones?\n\n```clojure\n(def routes\n (-\u003e (trail/resource :posts :except [:index :show])))\n \n ; =\u003e\n [\n  [:get    \"/posts/:id/fresh\" posts/fresh]\n  [:get    \"/posts/:id/edit\"  posts/edit]\n  [:post   \"/posts\"           posts/create]\n  [:put    \"/posts/:id\"       posts/change]\n  [:delete \"/posts/:id\"       posts/delete]\n ]\n```\n\n# Why?\n\nI like shortcuts, so rails resource routing really appealed to me. I also like clojure\nso I combined them.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswlkr%2Ftrail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswlkr%2Ftrail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswlkr%2Ftrail/lists"}