{"id":28379364,"url":"https://github.com/amberframework/amber-router","last_synced_at":"2025-09-02T06:33:40.745Z","repository":{"id":53165347,"uuid":"112485685","full_name":"amberframework/amber-router","owner":"amberframework","description":"A URL Routing shard. ","archived":false,"fork":false,"pushed_at":"2021-04-02T22:17:27.000Z","size":489,"stargazers_count":15,"open_issues_count":0,"forks_count":11,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-06-23T10:50:21.634Z","etag":null,"topics":["amber","comparison","crystal","fast","radix","router","web"],"latest_commit_sha":null,"homepage":"","language":"Crystal","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/amberframework.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","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-11-29T14:30:19.000Z","updated_at":"2024-08-12T19:34:24.000Z","dependencies_parsed_at":"2022-09-14T05:52:03.084Z","dependency_job_id":null,"html_url":"https://github.com/amberframework/amber-router","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/amberframework/amber-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amberframework%2Famber-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amberframework%2Famber-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amberframework%2Famber-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amberframework%2Famber-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amberframework","download_url":"https://codeload.github.com/amberframework/amber-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amberframework%2Famber-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273244306,"owners_count":25070958,"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-09-02T02:00:09.530Z","response_time":77,"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":["amber","comparison","crystal","fast","radix","router","web"],"created_at":"2025-05-30T02:38:13.784Z","updated_at":"2025-09-02T06:33:40.728Z","avatar_url":"https://github.com/amberframework.png","language":"Crystal","readme":"# Amber/Router [![Build Status](https://travis-ci.org/amberframework/amber-router.svg?branch=master)](https://travis-ci.org/amberframework/amber-router) [![Latest Release](https://img.shields.io/github/release/amberframework/amber-router.svg)](https://github.com/amberframework/amber-router/releases)\n\nA tree based url router with a similar API interface to [radix](https://github.com/luislavena/radix).\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  amber_router:\n    github: amberframework/amber-router\n```\n\n## Usage\n\n```crystal\nrequire \"amber_router\"\n\nroute_set = Amber::Router::RouteSet(Symbol).new\nroute_set.add \"/get/\", :root\n\n# A `:` at the start of a segment indicates a named parameter\nroute_set.add \"/get/users/:id\", :users\nroute_set.add \"/get/users/:id/books\", :users_books\n\n# A `*` at the start of a segment indicates a glob parameter\nroute_set.add \"/get/users/comments/*date_range\"\n\n# Supports storing multiple named arguments at the same position\nroute_set.add \"/get/users/:user_id/books/:23\", :user_book\n\n# Predictably matches by insertion order so route overloads work as expected\nroute_set.add \"/get/books/mine\", :my_books\nroute_set.add \"/get/books/:id\", :book\nroute_set.add \"/get/books/:id/chapters\", :book_chapters\n\n# Supports globs with a suffix\nroute_set.add \"/get/posts/*post_name/comments\", :wordpress_style\n\n# Supports match-all globs.\nroute_set.add \"/get/*\", :catch_all\n\n# Supports `Regex` based argument constraints\nroute_set.add \"/get/posts/:page\", :user_path, {\"page\" =\u003e /\\d+/}\nroute_set.add \"/get/test/:id\", :user_path, {\"id\" =\u003e /foo_\\d/}\n\nroute_set.find(\"/get/posts/1\").found? # =\u003e true\nroute_set.find(\"/get/posts/foo\").found? # =\u003e false\n\nroute_set.find(\"/get/test/foo_7\").found? # =\u003e true\nroute_set.find(\"/get/test/foo_\").found? # =\u003e false\n\n# Supports returning an array of matches.\n# Allows using custom logic based on each route's payload\n# to determine if a match could be found\nroute_set.add \"/user/:id\", :user_get\nroute_set.add \"/user/:id\", :user_delete\nroute_set.add \"/user/:id/posts\", :user_posts_get\n\nroute_set.find_routes(\"/user/10\").map \u0026.payload? # =\u003e [:user_get, :user_delete]\n\n# Finding routes from a payload:\nroute_set.find(\"/get/users/3\").payload # =\u003e :users\nroute_set.find(\"/get/users/3/books\").payload # =\u003e :users_books\nroute_set.find(\"/get/books/3\").payload # =\u003e :book\n\n# `RoutedResult` returns payload and named parameters\nresult = route_set.find(\"/get/posts/my_trip_to_kansas/comments\")\nresult.found? # =\u003e true\nresult.params # =\u003e {\"post_name\" =\u003e \"my_trip_to_kansas\"}\n```\n\n## Performance\n\n`crystal run examples/benchmark.cr --release` produces a comparison of this router and [radix](https://github.com/luislavena/radix). As of now, this is the comparison:\n\n```text\n$ crystal run examples/benchmark.cr --release\n\n/get/\namber_router: root   4.90M (203.95ns) (± 2.77%)  385B/op   1.16× slower\n       radix: root   5.70M (175.37ns) (± 3.84%)  224B/op        fastest\n\n/get/books/23/chapters\namber_router: deep   1.75M (571.75ns) (± 4.36%)  915B/op        fastest\n       radix: deep   1.50M (668.47ns) (± 4.31%)  544B/op   1.17× slower\n\n/get/books/23/pages\namber_router: wrong   2.64M (378.30ns) (± 5.51%)  593B/op        fastest\n       radix: wrong   1.74M (573.41ns) (± 2.84%)  464B/op   1.52× slower\n\n/get/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z\namber_router: many segments 501.49k (  1.99µs) (± 2.83%)  4.03kB/op   4.01× slower\n       radix: many segments   2.01M (496.78ns) (± 3.32%)    353B/op        fastest\n\n/get/var/2/3/4/5/6/7/8/9/0/1/2/3/4/5/6/7/8/9/0/1/2/3/4/5/6\namber_router: many variables 314.33k (  3.18µs) (± 3.33%)  6.05kB/op   1.41× slower\n       radix: many variables 442.56k (  2.26µs) (± 2.14%)  2.73kB/op        fastest\n\n/get/foobarbizfoobarbizfoobarbizfoobarbizfoobarbizbat/3\namber_router: long segments   1.95M (512.99ns) (± 2.24%)  786B/op        fastest\n       radix: long segments   1.12M (891.73ns) (± 2.41%)  576B/op   1.74× slower\n\n/post/products/23/reviews/\namber_router: catchall route   2.52M (396.60ns) (± 4.75%)  704B/op   1.49× slower\n       radix: catchall route   3.75M (266.85ns) (± 1.80%)  401B/op        fastest\n\n/put/products/Winter-Windproof-Trapper-Hat/dp/B01J7DAMCQ\nglobs with suffix match   1.33M (749.41ns) (± 1.85%)  1.25kB/op  fastest\n\nRoute constraints\n   route with a valid constraint   1.88M (531.64ns) (± 1.56%)  786B/op   1.43× slower\nroute with an invalid constraint   2.68M (372.50ns) (± 2.22%)  497B/op        fastest\n```\n\n## Contributing\n\nContributions are welcome. Please fork the repository, commit changes on a branch, and then open a pull request. Please include the output of `examples/benchmark.cr` as an update to this readme.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famberframework%2Famber-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famberframework%2Famber-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famberframework%2Famber-router/lists"}