{"id":13786699,"url":"https://github.com/gookit/rux","last_synced_at":"2025-10-31T08:35:04.741Z","repository":{"id":38354867,"uuid":"143588305","full_name":"gookit/rux","owner":"gookit","description":"⚡ Rux is an simple and fast web framework. support route group, param route binding, middleware, compatible http.Handler interface. 简单且快速的 Go api/web 框架，支持路由分组，路由参数绑定，中间件，兼容 http.Handler 接口","archived":false,"fork":false,"pushed_at":"2025-03-13T01:58:59.000Z","size":783,"stargazers_count":97,"open_issues_count":2,"forks_count":16,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T04:07:57.065Z","etag":null,"topics":["go","http-handler","http-middleware","http-router","http-server","middleware","mux","router"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/gookit/rux?tab=doc","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/gookit.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-05T06:13:57.000Z","updated_at":"2025-03-13T01:58:57.000Z","dependencies_parsed_at":"2023-02-18T03:01:33.008Z","dependency_job_id":"9f532af8-4e6a-473f-803c-f53a65943949","html_url":"https://github.com/gookit/rux","commit_stats":null,"previous_names":["gookit/sux"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Frux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Frux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Frux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gookit%2Frux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gookit","download_url":"https://codeload.github.com/gookit/rux/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289427,"owners_count":20914464,"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":["go","http-handler","http-middleware","http-router","http-server","middleware","mux","router"],"created_at":"2024-08-03T19:01:29.395Z","updated_at":"2025-10-31T08:35:04.736Z","avatar_url":"https://github.com/gookit.png","language":"Go","readme":"# Rux\n\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/gookit/rux?style=flat-square)\n[![Actions Status](https://github.com/gookit/rux/workflows/Unit-Tests/badge.svg)](https://github.com/gookit/rux/actions)\n[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/gookit/rux)](https://github.com/gookit/rux)\n[![GoDoc](https://pkg.go.dev/badge/github.com/gookit/rux.svg)](https://pkg.go.dev/github.com/gookit/rux?tab=doc)\n[![Coverage Status](https://coveralls.io/repos/github/gookit/rux/badge.svg?branch=master)](https://coveralls.io/github/gookit/rux?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/gookit/rux)](https://goreportcard.com/report/github.com/gookit/rux)\n\nSimple and fast web framework for build golang HTTP applications.\n\n- Fast route match, support route group\n- Support route path params and named routing\n- Support cache recently accessed dynamic routes\n- Support route middleware, group middleware, global middleware\n- Support quickly add a `RESETFul` or `Controller` style structs\n- Support generic `http.Handler` interface middleware\n- Support static file access handle\n- Support add handlers for handle `NotFound` and `NotAllowed`\n\n## [中文说明](README.zh-CN.md)\n\n中文说明请看 **[README.zh-CN](README.zh-CN.md)**\n\n## GoDoc\n\n- [godoc for github](https://pkg.go.dev/github.com/gookit/rux?tab=doc)\n\n## Install\n\n```bash\ngo get github.com/gookit/rux\n```\n\n## Quick start\n\n```go\npackage main\n\nimport (\n\t\"github.com/gookit/rux\"\n)\n\nfunc main() {\n\tr := rux.New()\n\t\n\t// Add Routes:\n\tr.GET(\"/\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello\")\n\t})\n\tr.GET(\"/hello/{name}\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello \" + c.Param(\"name\"))\n\t})\n\tr.POST(\"/post\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello\")\n\t})\n\t// add multi method support for an route path\n\tr.Add(\"/post[/{id}]\", func(c *rux.Context) {\n\t\tif c.Param(\"id\") == \"\" {\n\t\t\t// do create post\n\t\t\tc.Text(200, \"created\")\n\t\t\treturn\n\t\t}\n\n\t\tid := c.Params.Int(\"id\")\n\t\t// do update post\n\t\tc.Text(200, \"updated \" + fmt.Sprint(id))\n\t}, rux.POST, rux.PUT)\n\n\t// Start server\n\tr.Listen(\":8080\")\n\t// can also\n\t// http.ListenAndServe(\":8080\", r)\n}\n```\n\n## Route Group\n\n```go\nr.Group(\"/articles\", func() {\n    r.GET(\"\", func(c *rux.Context) {\n        c.Text(200, \"view list\")\n    })\n    r.POST(\"\", func(c *rux.Context) {\n        c.Text(200, \"create ok\")\n    })\n    r.GET(`/{id:\\d+}`, func(c *rux.Context) {\n        c.Text(200, \"view detail, id: \" + c.Param(\"id\"))\n    })\n})\n```\n\n## Path Params\n\nYou can add the path params like: `{id}` Or `{id:\\d+}`\n\n```go\n// can access by: \"/blog/123\"\nr.GET(`/blog/{id:\\d+}`, func(c *rux.Context) {\n    c.Text(200, \"view detail, id: \" + c.Param(\"id\"))\n})\n```\n\noptional params, like `/about[.html]` or `/posts[/{id}]`:\n\n```go\n// can access by: \"/blog/my-article\" \"/blog/my-article.html\"\nr.GET(`/blog/{title:\\w+}[.html]`, func(c *rux.Context) {\n    c.Text(200, \"view detail, id: \" + c.Param(\"id\"))\n})\n\nr.Add(\"/posts[/{id}]\", func(c *rux.Context) {\n    if c.Param(\"id\") == \"\" {\n        // do create post\n        c.Text(200, \"created\")\n        return\n    }\n\n    id := c.Params.Int(\"id\")\n    // do update post\n    c.Text(200, \"updated \" + fmt.Sprint(id))\n}, rux.POST, rux.PUT)\n```\n\n## Use Middleware\n\nrux support use middleware, allow:\n\n- global middleware\n- group middleware\n- route middleware\n\n**Call priority**: `global middleware -\u003e group middleware -\u003e route middleware`\n\nExamples:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/gookit/rux\"\n)\n\nfunc main() {\n\tr := rux.New()\n\t\n\t// add global middleware\n\tr.Use(func(c *rux.Context) {\n\t    // do something ...\n\t})\n\t\n\t// add middleware for the route\n\troute := r.GET(\"/middle\", func(c *rux.Context) { // main handler\n\t\tc.WriteString(\"-O-\")\n\t}, func(c *rux.Context) { // middle 1\n        c.WriteString(\"a\")\n        c.Next() // Notice: call Next()\n        c.WriteString(\"A\")\n        // if call Abort(), will abort at the end of this middleware run\n        // c.Abort() \n    })\n\t\n\t// add more by Use()\n\troute.Use(func(c *rux.Context) { // middle 2\n\t\tc.WriteString(\"b\")\n\t\tc.Next()\n\t\tc.WriteString(\"B\")\n\t})\n\n\t// now, access the URI /middle\n\t// will output: ab-O-BA\n}\n```\n\n- **Call sequence**: `middle 1 -\u003e middle 2 -\u003e main handler -\u003e middle 2 -\u003e middle 1`\n- **Flow chart**:\n\n```text\n        +-----------------------------+\n        | middle 1                    |\n        |  +----------------------+   |\n        |  | middle 2             |   |\n start  |  |  +----------------+  |   | end\n-------\u003e|  |  |  main handler  |  |   |---\u003e----\n        |  |  |________________|  |   |    \n        |  |______________________|   |  \n        |_____________________________|\n```\n\n\u003e more please see [middleware_test.go](middleware_test.go) middleware tests\n\n## Use http.Handler\n\nrux is support generic `http.Handler` interface middleware\n\n\u003e You can use `rux.WrapHTTPHandler()` convert `http.Handler` as `rux.HandlerFunc`\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\t\n\t\"github.com/gookit/rux\"\n\t// here we use gorilla/handlers, it provides some generic handlers.\n\t\"github.com/gorilla/handlers\"\n)\n\nfunc main() {\n\tr := rux.New()\n\t\n\t// create a simple generic http.Handler\n\th0 := http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {\n\t\tw.Header().Set(\"new-key\", \"val\")\n\t})\n\t\n\tr.Use(rux.WrapHTTPHandler(h0), rux.WrapHTTPHandler(handlers.ProxyHeaders()))\n\t\n\tr.GET(\"/\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello\")\n\t})\n\t// add routes ...\n\t\n    // Wrap our server with our gzip handler to gzip compress all responses.\n    http.ListenAndServe(\":8000\", handlers.CompressHandler(r))\n}\n```\n\n## More Usage\n\n### Static Assets\n\n```go\npackage main\n\nimport (\n\t\"embed\"\t\n\t\"net/http\"\n\n\t\"github.com/gookit/rux\"\n)\n\n//go:embed static\nvar embAssets embed.FS\n\nfunc main() {\n\tr := rux.New()\n\n\t// one file\n\tr.StaticFile(\"/site.js\", \"testdata/site.js\")\n\n\t// allow any files in the directory.\n\tr.StaticDir(\"/static\", \"testdata\")\n\n\t// file type limit in the directory\n\tr.StaticFiles(\"/assets\", \"testdata\", \"css|js\")\n\n\t// go 1.16+: use embed assets. access: /embed/static/some.html\n\tr.StaticFS(\"/embed\", http.FS(embAssets))\n}\n```\n\n### Name Route\n\nIn `rux`, you can add a named route, and you can get the corresponding route instance(`rux.Route`) from the router according to the name.\n\nExamples：\n\n```go\n\tr := rux.New()\n\t\n\t// Method 1\n\tmyRoute := rux.NewNamedRoute(\"name1\", \"/path4/some/{id}\", emptyHandler, \"GET\")\n\tr.AddRoute(myRoute)\n\n\t// Method 2\n\trux.AddNamed(\"name2\", \"/\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello\")\n\t})\n\n\t// Method 3\n\tr.GET(\"/hi\", func(c *rux.Context) {\n\t\tc.Text(200, \"hello\")\n\t}).NamedTo(\"name3\", r)\n\t\n\t// get route by name\n\tmyRoute = r.GetRoute(\"name1\")\n```\n\n### Redirect\n\nredirect to other page\n\n```go\nr.GET(\"/\", func(c *rux.Context) {\n    c.AbortThen().Redirect(\"/login\", 302)\n})\n\n// Or\nr.GET(\"/\", func(c *rux.Context) {\n    c.Redirect(\"/login\", 302)\n    c.Abort()\n})\n\nr.GET(\"/\", func(c *rux.Context) {\n    c.Back()\n    c.Abort()\n})\n```\n\n### Cookies\n\nyou can quick operate cookies by `FastSetCookie()` `DelCookie()`\n\n\u003e Note: You must set or delete cookies before writing BODY content\n\n```go\nr.GET(\"/setcookie\", func(c *rux.Context) {\n    c.FastSetCookie(\"rux_cookie2\", \"test-value2\", 3600)\n    c.SetCookie(\"rux_cookie\", \"test-value1\", 3600, \"/\", c.Req.URL.Host, false, true)\n\tc.WriteString(\"hello, in \" + c.URL().Path)\n})\n\nr.GET(\"/delcookie\", func(c *rux.Context) {\n\tval := ctx.Cookie(\"rux_cookie\") // \"test-value1\"\n\tc.DelCookie(\"rux_cookie\", \"rux_cookie2\")\n})\n```\n\n### Multi Domains\n\n\u003e code is refer from `julienschmidt/httprouter`\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/gookit/rux\"\n)\n\ntype HostSwitch map[string]http.Handler\n\n// Implement the ServeHTTP method on our new type\nfunc (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\t// Check if a http.Handler is registered for the given host.\n\t// If yes, use it to handle the request.\n\tif router := hs[r.Host]; router != nil {\n\t\trouter.ServeHTTP(w, r)\n\t} else {\n\t\t// Handle host names for which no handler is registered\n\t\thttp.Error(w, \"Forbidden\", 403) // Or Redirect?\n\t}\n}\n\nfunc main() {\n\t// Initialize a router as usual\n\trouter := rux.New()\n\trouter.GET(\"/\", Index)\n\trouter.GET(\"/hello/{name}\", func(c *rux.Context) {})\n\n\t// Make a new HostSwitch and insert the router (our http handler)\n\t// for example.com and port 12345\n\ths := make(HostSwitch)\n\ths[\"example.com:12345\"] = router\n\n\t// Use the HostSwitch to listen and serve on port 12345\n\tlog.Fatal(http.ListenAndServe(\":12345\", hs))\n}\n```\n\n### RESETFul Style\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/gookit/rux\"\n)\n\ntype Product struct {\n}\n\n// Uses middlewares [optional]\nfunc (Product) Uses() map[string][]rux.HandlerFunc {\n\treturn map[string][]rux.HandlerFunc{\n\t\t// function name: handlers\n\t\t\"Delete\": []rux.HandlerFunc{\n\t\t\thandlers.HTTPBasicAuth(map[string]string{\"test\": \"123\"}),\n\t\t\thandlers.GenRequestID(),\n\t\t},\n\t}\n}\n\n// all products [optional]\nfunc (p *Product) Index(c *rux.Context) {\n\t// do something\n}\n\n// create product [optional]\nfunc (p *Product) Create(c *rux.Context) {\n\t// do something\n}\n\n// save new product [optional]\nfunc (p *Product) Store(c *rux.Context) {\n\t// do something\n}\n\n// show product with {id} [optional]\nfunc (p *Product) Show(c *rux.Context) {\n\t// do something\n}\n\n// edit product [optional]\nfunc (p *Product) Edit(c *rux.Context) {\n\t// do something\n}\n\n// save edited product [optional]\nfunc (p *Product) Update(c *rux.Context) {\n\t// do something\n}\n\n// delete product [optional]\nfunc (p *Product) Delete(c *rux.Context) {\n\t// do something\n}\n\nfunc main() {\n\trouter := rux.New()\n\n\t// methods\tPath\tAction\tRoute Name\n    // GET\t/product\tindex\tproduct_index\n    // GET\t/product/create\tcreate\tproduct_create\n    // POST\t/product\tstore\tproduct_store\n    // GET\t/product/{id}\tshow\tproduct_show\n    // GET\t/product/{id}/edit\tedit\tproduct_edit\n    // PUT/PATCH\t/product/{id}\tupdate\tproduct_update\n    // DELETE\t/product/{id}\tdelete\tproduct_delete\n    // resetful style\n\trouter.Resource(\"/\", new(Product))\n\n\tlog.Fatal(http.ListenAndServe(\":12345\", router))\n}\n```\n\n### Controller Style\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/gookit/rux\"\n)\n\n// News controller\ntype News struct {\n}\n\nfunc (n *News) AddRoutes(g *rux.Router) {\n\tg.GET(\"/\", n.Index)\n\tg.POST(\"/\", n.Create)\n\tg.PUT(\"/\", n.Edit)\n}\n\nfunc (n *News) Index(c *rux.Context) {\n\t// Do something\n}\n\nfunc (n *News) Create(c *rux.Context) {\n\t// Do something\n}\n\nfunc (n *News) Edit(c *rux.Context) {\n\t// Do something\n}\n\nfunc main() {\n\trouter := rux.New()\n\n\t// controller style\n\trouter.Controller(\"/news\", new(News))\n\n\tlog.Fatal(http.ListenAndServe(\":12345\", router))\n}\n```\n\n### Build URL\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/gookit/rux\"\n)\n\nfunc main() {\n\t// Initialize a router as usual\n\trouter := rux.New()\n\trouter.GET(`/news/{category_id}/{new_id:\\d+}/detail`, func(c *rux.Context) {\n\t\tvar u = make(url.Values)\n        u.Add(\"username\", \"admin\")\n        u.Add(\"password\", \"12345\")\n\t\t\n\t\tb := rux.NewBuildRequestURL()\n        // b.Scheme(\"https\")\n        // b.Host(\"www.mytest.com\")\n        b.Queries(u)\n        b.Params(rux.M{\"{category_id}\": \"100\", \"{new_id}\": \"20\"})\n\t\t// b.Path(\"/dev\")\n        // println(b.Build().String())\n        \n        println(c.Router().BuildRequestURL(\"new_detail\", b).String())\n\t\t// result:  /news/100/20/detail?username=admin\u0026password=12345\n\t\t// get current route name\n\t\tif c.MustGet(rux.CTXCurrentRouteName) == \"new_detail\" {\n            // post data etc....\n        }\n\t}).NamedTo(\"new_detail\", router)\n\n\t// Use the HostSwitch to listen and serve on port 12345\n\tlog.Fatal(http.ListenAndServe(\":12345\", router))\n}\n```\n\n## Help\n\n- lint\n\n```bash\ngolint ./...\n```\n\n- format check\n\n```bash\n# list error files\ngofmt -s -l ./\n# fix format and write to file\ngofmt -s -w some.go\n```\n\n- unit test\n\n```bash\ngo test -cover ./...\n```\n\n## Gookit Packages\n\n- [gookit/ini](https://github.com/gookit/ini) Go config management, use INI files\n- [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP \n- [gookit/gcli](https://github.com/gookit/gcli) build CLI application, tool library, running CLI commands\n- [gookit/slog](https://github.com/gookit/slog) Concise and extensible go log library\n- [gookit/event](https://github.com/gookit/event) Lightweight event manager and dispatcher implements by Go\n- [gookit/cache](https://github.com/gookit/cache) Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached.\n- [gookit/config](https://github.com/gookit/config) Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags\n- [gookit/color](https://github.com/gookit/color) A command-line color library with true color support, universal API methods and Windows support\n- [gookit/filter](https://github.com/gookit/filter) Provide filtering, sanitizing, and conversion of golang data\n- [gookit/validate](https://github.com/gookit/validate) Use for data validation and filtering. support Map, Struct, Form data\n- [gookit/goutil](https://github.com/gookit/goutil) Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more\n- More please see https://github.com/gookit\n\n## See also\n\n- https://github.com/gin-gonic/gin\n- https://github.com/gorilla/mux\n- https://github.com/julienschmidt/httprouter\n- https://github.com/xialeistudio/go-dispatcher\n\n## License\n\n**[MIT](LICENSE)**\n","funding_links":[],"categories":["Web Frameworks","Utility","web框架`web 框架`","Web框架","web框架"],"sub_categories":["Utility/Miscellaneous","版本控制`版本控制相关库`","HTTP Clients","实用程序/Miscellaneous","版本控制","Fail injection"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgookit%2Frux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgookit%2Frux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgookit%2Frux/lists"}