{"id":13764091,"url":"https://github.com/gowww/router","last_synced_at":"2026-01-12T01:51:23.928Z","repository":{"id":57481104,"uuid":"92392508","full_name":"gowww/router","owner":"gowww","description":"⚡️ A lightning fast HTTP router","archived":false,"fork":false,"pushed_at":"2023-09-11T15:16:54.000Z","size":51,"stargazers_count":185,"open_issues_count":0,"forks_count":13,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-08-13T17:43:07.167Z","etag":null,"topics":["fast","go","golang","handler","http","optimization","performance","regular-expression","router","routing","server","trie","wildcard"],"latest_commit_sha":null,"homepage":"","language":"Go","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/gowww.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-05-25T10:29:27.000Z","updated_at":"2024-05-23T13:10:06.000Z","dependencies_parsed_at":"2024-01-08T16:08:45.226Z","dependency_job_id":"91c58880-85e2-4b11-9e8c-70fe4882753c","html_url":"https://github.com/gowww/router","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gowww/router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gowww%2Frouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gowww%2Frouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gowww%2Frouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gowww%2Frouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gowww","download_url":"https://codeload.github.com/gowww/router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gowww%2Frouter/sbom","scorecard":{"id":442490,"data":{"date":"2025-08-11","repo":{"name":"github.com/gowww/router","commit":"c69c94ad4594a6f0a6bda41595cfbba44cdf71a5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T05:52:28.564Z","repository_id":57481104,"created_at":"2025-08-19T05:52:28.564Z","updated_at":"2025-08-19T05:52:28.564Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28331257,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"ssl_error","status_checked_at":"2026-01-12T00:36:15.229Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["fast","go","golang","handler","http","optimization","performance","regular-expression","router","routing","server","trie","wildcard"],"created_at":"2024-08-03T15:01:13.516Z","updated_at":"2026-01-12T01:51:23.911Z","avatar_url":"https://github.com/gowww.png","language":"Go","readme":"# [![gowww](https://avatars.githubusercontent.com/u/18078923?s=20)](https://github.com/gowww) router [![GoDoc](https://godoc.org/github.com/gowww/router?status.svg)](https://godoc.org/github.com/gowww/router) [![Build](https://travis-ci.org/gowww/router.svg?branch=master)](https://travis-ci.org/gowww/router) [![Coverage](https://coveralls.io/repos/github/gowww/router/badge.svg?branch=master)](https://coveralls.io/github/gowww/router?branch=master) [![Go Report](https://goreportcard.com/badge/github.com/gowww/router)](https://goreportcard.com/report/github.com/gowww/router) ![Status Stable](https://img.shields.io/badge/status-stable-brightgreen.svg)\n\nPackage [router](https://godoc.org/github.com/gowww/router) provides a lightning fast HTTP router.\n\n- [Features](#features)\n- [Installing](#installing)\n- [Usage](#usage)\n\t- [Parameters](#parameters)\n\t\t- [Named](#named)\n\t\t- [Regular expressions](#regular-expressions)\n\t\t- [Wildcard](#wildcard)\n\t- [Static files](#static-files)\n\t- [Custom \"not found\" handler](#custom-not-found-handler)\n\n## Features\n\n- Extreme performance: [sub-microsecond routing](https://gist.github.com/xthezealot/bb632f6b104deb2a50ce476c25f7bec2) in most cases\n- Full compatibility with the [http.Handler](https://golang.org/pkg/net/http/#Handler) interface\n- Generic: no magic methods, bring your own handlers\n- Path parameters, regular expressions and wildcards\n- Smart prioritized routes\n- Zero memory allocations during serving (but for parameters)\n- Respecting the principle of least surprise\n- Tested and used in production\n\n## Installing\n\n1. Get package:\n\n\t```Shell\n\tgo get -u github.com/gowww/router\n\t```\n\n2. Import it in your code:\n\n\t```Go\n\timport \"github.com/gowww/router\"\n\t```\n\n## Usage\n\n1. Make a new router:\n\n\t```Go\n\trt := router.New()\n\t```\n\n2. Make a route:\n\n\t```Go\n\trt.Handle(\"GET\", \"/\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprint(w, \"Hello\")\n\t}))\n\t```\n\n\tRemember that HTTP methods are case-sensitive and uppercase by convention ([RFC 7231 4.1](https://tools.ietf.org/html/rfc7231#section-4.1)).  \n\tSo you can directly use the built-in shortcuts for standard HTTP methods: [Router.Get](https://godoc.org/github.com/gowww/router#Router.Get), [Router.Post](https://godoc.org/github.com/gowww/router#Router.Post), [Router.Put](https://godoc.org/github.com/gowww/router#Router.Put), [Router.Patch](https://godoc.org/github.com/gowww/router#Router.Patch) and [Router.Delete](https://godoc.org/github.com/gowww/router#Router.Delete).\n\n3. Give the router to the server:\n\n\t```Go\n\thttp.ListenAndServe(\":8080\", rt)\n\t```\n\n### Parameters\n\n#### Named\n\nA named parameter begins with `:` and matches any value until the next `/` or end of path.\n\nTo retrieve the value (stored in request's context), ask [Parameter](https://godoc.org/github.com/gowww/router#Parameter).  \nIt will return the value as a string.\n\nExample, with a parameter `id`:\n\n```Go\nrt.Get(\"/users/:id\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tid := router.Parameter(r, \"id\")\n\tfmt.Fprintf(w, \"Page of user #%s\", id)\n}))\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eNo surprise\u003c/summary\u003e\n\nA parameter can be used on the same level as a static route, without conflict:\n\n```Go\nrt.Get(\"/users/all\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprint(w, \"All users page\")\n}))\n\nrt.Get(\"/users/:id\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tid := router.Parameter(r, \"id\")\n\tfmt.Fprintf(w, \"Page of user #%s\", id)\n}))\n```\n\u003c/details\u003e\n\n#### Regular expressions\n\nIf a parameter must match an exact pattern (digits only, for example), you can also set a [regular expression](https://golang.org/pkg/regexp/syntax) constraint just after the parameter name and another `:`:\n\n```Go\nrt.Get(`/users/:id:^\\d+$`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tid := router.Parameter(r, \"id\")\n\tfmt.Fprintf(w, \"Page of user #%s\", id)\n}))\n```\n\nIf you don't need to retrieve the parameter value but only use a regular expression, you can omit the parameter name:\n\n```Go\nrt.Get(`/shows/::^prison-break-s06-.+`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprint(w, \"Prison Break S06 — Coming soon…\")\n}))\n```\n\nDon't forget that regular expressions can significantly reduce performance.\n\n\u003cdetails\u003e\n\u003csummary\u003eNo surprise\u003c/summary\u003e\n\nA parameter with a regular expression can be used on the same level as a simple parameter, without conflict:\n\n```Go\nrt.Get(`/users/:id:^\\d+$`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tid := router.Parameter(r, \"id\")\n\tfmt.Fprintf(w, \"Page of user #%s\", id)\n}))\n\nrt.Get(\"/users/:name\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tname := router.Parameter(r, \"name\")\n\tfmt.Fprintf(w, \"Page of %s\", name)\n}))\n```\n\u003c/details\u003e\n\n#### Wildcard\n\nA trailing slash in a route path is significant.  \nIt behaves like a wildcard by matching the beginning of the request path.  \nThe rest of the request path becomes the parameter value of `*`:\n\n```Go\nrt.Get(\"/files/\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfilepath := router.Parameter(r, \"*\")\n\tfmt.Fprintf(w, \"Get file %s\", filepath)\n}))\n```\n\nNote that a trailing slash in a request path is always trimmed and the client redirected.  \nFor example, a request for `/files/` will be redirected to `/files` and will never match a `/files/` route.  \nIn other words, `/files` and `/files/` are two different routes.\n\n\u003cdetails\u003e\n\u003csummary\u003eNo surprise\u003c/summary\u003e\n\nDeeper route paths with the same prefix as the wildcard will take precedence, without conflict:\n\n```Go\n// Will match:\n// \t/files/one\n// \t/files/two\n// \t...\nrt.Get(\"/files/:name\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {kv\n\tname := router.Parameter(r, \"name\")\n\tfmt.Fprintf(w, \"Get root file #%s\", name)\n}))\n\n// Will match:\n// \t/files/one/...\n// \t/files/two/...\n// \t...\nrt.Get(\"/files/\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfilepath := router.Parameter(r, \"*\")\n\tfmt.Fprintf(w, \"Get file %s\", filepath)\n}))\n\n// Will match:\n// \t/files/movies/one\n// \t/files/movies/two\n// \t...\nrt.Get(\"/files/movies/:name\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tname := router.Parameter(r, \"name\")\n\tfmt.Fprintf(w, \"Get movie #%s\", name)\n}))\n```\n\u003c/details\u003e\n\n### Static files\n\nFor serving static files, like for other routes, just bring your own handler.\n\nExample, with the standard [net/http.FileServer](https://golang.org/pkg/net/http#FileServer):\n\n```Go\nrt.Get(\"/static/\", http.StripPrefix(\"/static/\", http.FileServer(http.Dir(\"static\"))))\n```\n\n### Custom \"not found\" handler\n\nWhen a request match no route, the response status is set to 404 and an empty body is sent by default.\n\nBut you can set your own \"not found\" handler.  \nIn this case, it's up to you to set the response status code (normally 404):\n\n```Go\nrt.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\thttp.NotFound(w, r)\n})\n```\n","funding_links":[],"categories":["Web Frameworks","Web框架","Routers","路由"],"sub_categories":["Routers","路由器","HTTP Clients","创建http中间件的代码库"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgowww%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgowww%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgowww%2Frouter/lists"}