{"id":13367432,"url":"https://github.com/Gowww/router","last_synced_at":"2025-03-12T18:32:41.826Z","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":8,"default_branch":"master","last_synced_at":"2024-11-16T23:32:33.511Z","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,"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","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243271657,"owners_count":20264502,"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":["fast","go","golang","handler","http","optimization","performance","regular-expression","router","routing","server","trie","wildcard"],"created_at":"2024-07-30T00:01:48.675Z","updated_at":"2025-03-12T18:32:41.529Z","avatar_url":"https://github.com/gowww.png","language":"Go","funding_links":[],"categories":["XML"],"sub_categories":["路由"],"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","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"}