2025年3月25日 星期二 甲辰(龙)年 月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Go语言

gookit/rux 简单且快速的 Go Web 框架

时间:12-14来源:作者:点击数:5

rux 简单且快速的 Go web 框架,支持中间件,兼容 http.Handler 接口。

NOTICE: v1.3.x 不完全兼容 v1.2.x 版本

  • 支持路由参数,支持路由组,支持给路由命名
  • 支持方便的静态文件/目录处理
  • 支持缓存最近访问的动态路由以获得更高性能
  • 支持中间件: 路由中间件,组中间件,全局中间件
  • 兼容支持 http.Handler 接口,可以直接使用其他的常用中间件
  • 支持添加 NotFound 和 NotAllowed 处理
  • 支持添加 Error 和 Panic 处理错误或异常

安装

  • go get github.com/gookit/rux

快速开始

  • package main
  • import (
  • "github.com/gookit/rux"
  • )
  • func main() {
  • r := rux.New()
  • // ===== 静态资源
  • // 单个文件
  • r.StaticFile("/site.js", "testdata/site.js")
  • // 静态资源目录
  • r.StaticDir("/static", "testdata")
  • // 静态资源目录,但是有后缀限制
  • r.StaticFiles("/assets", "testdata", "css|js")
  • // ===== 添加路由
  • r.GET("/", func(c *rux.Context) {
  • c.Text(200, "hello")
  • })
  • r.GET("/hello/{name}", func(c *rux.Context) {
  • c.Text(200, "hello " + c.Param("name"))
  • })
  • r.POST("/post", func(c *rux.Context) {
  • c.Text(200, "hello")
  • })
  • r.Group("/articles", func() {
  • r.GET("", func(c *rux.Context) {
  • c.Text(200, "view list")
  • })
  • r.POST("", func(c *rux.Context) {
  • c.Text(200, "create ok")
  • })
  • r.GET(`/{id:\d+}`, func(c *rux.Context) {
  • c.Text(200, "view detail, id: " + c.Param("id"))
  • })
  • })
  • // 快速添加多个METHOD支持
  • r.Add("/post[/{id}]", func(c *rux.Context) {
  • if c.Param("id") == "" {
  • // do create post
  • c.Text(200, "created")
  • return
  • }
  • id := c.Params.Int("id")
  • // do update post
  • c.Text(200, "updated " + fmt.Sprint(id))
  • }, rux.POST, rux.PUT)
  • // 启动服务并监听
  • r.Listen(":8080")
  • // 也可以
  • // http.ListenAndServe(":8080", r)
  • }

使用中间件

支持使用中间件:

  • 全局中间件
  • 路由组中间件
  • 路由中间件

调用优先级全局中间件 -> 路由组中间件 -> 路由中间件

使用示例:

  • package main
  • import (
  • "fmt"
  • "github.com/gookit/rux"
  • )
  • func main() {
  • r := rux.New()
  • // 添加一个全局中间件
  • r.Use(func(c *rux.Context) {
  • // do something ...
  • })
  • // 通过参数添加中间件
  • route := r.GET("/middle", func(c *rux.Context) { // main handler
  • c.WriteString("-O-")
  • }, func(c *rux.Context) { // middle 1
  • c.WriteString("a")
  • c.Next() // Notice: call Next()
  • c.WriteString("A")
  • // if call Abort(), will abort at the end of this middleware run
  • // c.Abort()
  • })
  • // 通过 Use() 添加中间件
  • route.Use(func(c *rux.Context) { // middle 2
  • c.WriteString("b")
  • c.Next()
  • c.WriteString("B")
  • })
  • // 启动server访问: /middle
  • // 将会看到输出: ab-O-BA
  • }
  • 调用流程图:
  • +-----------------------------+
  • | middle 1 |
  • | +----------------------+ |
  • | | middle 2 | |
  • start | | +----------------+ | | end
  • ------->| | | main handler | | |--->----
  • | | |________________| | |
  • | |______________________| |
  • |_____________________________|

更多的使用请查看 middleware_test.go 中间件测试

使用http.Handler

rux 支持通用的 http.Handler 接口中间件

你可以使用 rux.WrapHTTPHandler() 转换 http.Handler 为 rux.HandlerFunc

  • package main
  • import (
  • "net/http"
  • "github.com/gookit/rux"
  • // 这里我们使用 gorilla/handlers,它提供了一些通用的中间件
  • "github.com/gorilla/handlers"
  • )
  • func main() {
  • r := rux.New()
  • // create a simple generic http.Handler
  • h0 := http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
  • w.Header().Set("new-key", "val")
  • })
  • r.Use(rux.WrapHTTPHandler(h0), rux.WrapHTTPHandler(handlers.ProxyHeaders()))
  • r.GET("/", func(c *rux.Context) {
  • c.Text(200, "hello")
  • })
  • // add routes ...
  • // Wrap our server with our gzip handler to gzip compress all responses.
  • http.ListenAndServe(":8000", handlers.CompressHandler(r))
  • }

更多功能

路由命名

rux 中你可以添加命名路由,根据名称可以从路由器里拿到对应的路由实例 rux.Route

有几种方式添加命名路由:

  • r := rux.New()
  • // Method 1
  • myRoute := rux.NewNamedRoute("name1", "/path4/some/{id}", emptyHandler, "GET")
  • r.AddRoute(myRoute)
  • // Method 2
  • rux.AddNamed("name2", "/", func(c *rux.Context) {
  • c.Text(200, "hello")
  • })
  • // Method 3
  • r.GET("/hi", func(c *rux.Context) {
  • c.Text(200, "hello")
  • }).NamedTo("name3", r)
  • // get route by name
  • myRoute = r.GetRoute("name1")

重定向跳转

  • r.GET("/", func(c *rux.Context) {
  • c.AbortThen().Redirect("/login", 302)
  • })
  • // Or
  • r.GET("/", func(c *rux.Context) {
  • c.Redirect("/login", 302)
  • c.Abort()
  • })
  • r.GET("/", func(c *rux.Context) {
  • c.Back()
  • c.Abort()
  • })

操作Cookies

您可以通过以下方式快速操作Cookies FastSetCookie() DelCookie()

注意:您必须先设置或删除Cookies,然后再调用写入BODY内容的相关方法

  • r.GET("/setcookie", func(c *rux.Context) {
  • c.FastSetCookie("rux_cookie2", "test-value2", 3600)
  • c.SetCookie("rux_cookie", "test-value1", 3600, "/", c.Req.URL.Host, false, true)
  • c.WriteString("hello, in " + c.URL().Path)
  • })
  • r.GET("/delcookie", func(c *rux.Context) {
  • val := ctx.Cookie("rux_cookie") // "test-value1"
  • c.DelCookie("rux_cookie", "rux_cookie2")
  • })

多个域名

code is ref from julienschmidt/httprouter

  • package main
  • import (
  • "log"
  • "net/http"
  • "github.com/gookit/rux"
  • )
  • type HostSwitch map[string]http.Handler
  • // Implement the ServeHTTP method on our new type
  • func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  • // Check if a http.Handler is registered for the given host.
  • // If yes, use it to handle the request.
  • if router := hs[r.Host]; router != nil {
  • router.ServeHTTP(w, r)
  • } else {
  • // Handle host names for which no handler is registered
  • http.Error(w, "Forbidden", 403) // Or Redirect?
  • }
  • }
  • func main() {
  • // Initialize a router as usual
  • router := rux.New()
  • router.GET("/", Index)
  • router.GET("/hello/{name}", func(c *rux.Context) {})
  • // Make a new HostSwitch and insert the router (our http handler)
  • // for example.com and port 12345
  • hs := make(HostSwitch)
  • hs["example.com:12345"] = router
  • // Use the HostSwitch to listen and serve on port 12345
  • log.Fatal(http.ListenAndServe(":12345", hs))
  • }

RESETful 风格

  • package main
  • import (
  • "log"
  • "net/http"
  • "github.com/gookit/rux"
  • )
  • type Product struct {
  • }
  • // middlewares [optional]
  • func (Product) Uses() map[string][]rux.HandlerFunc {
  • return map[string][]rux.HandlerFunc{
  • // function name: handlers
  • "Delete": []rux.HandlerFunc{
  • handlers.HTTPBasicAuth(map[string]string{"test": "123"}),
  • handlers.GenRequestID(),
  • },
  • }
  • }
  • // all products [optional]
  • func (p *Product) Index(c *rux.Context) {
  • // do something ...
  • }
  • // create product [optional]
  • func (p *Product) Create(c *rux.Context) {
  • // do something ...
  • }
  • // save new product [optional]
  • func (p *Product) Store(c *rux.Context) {
  • // do something ...
  • }
  • // show product with {id} [optional]
  • func (p *Product) Show(c *rux.Context) {
  • // do something ...
  • }
  • // edit product [optional]
  • func (p *Product) Edit(c *rux.Context) {
  • // do something ...
  • }
  • // save edited product [optional]
  • func (p *Product) Update(c *rux.Context) {
  • // do something ...
  • }
  • // delete product [optional]
  • func (p *Product) Delete(c *rux.Context) {
  • // do something ...
  • }
  • func main() {
  • router := rux.New()
  • // methods Path Action Route Name
  • // GET /product index product_index
  • // GET /product/create create product_create
  • // POST /product store product_store
  • // GET /product/{id} show product_show
  • // GET /product/{id}/edit edit product_edit
  • // PUT/PATCH /product/{id} update product_update
  • // DELETE /product/{id} delete product_delete
  • // resetful style
  • router.Resource("/", new(Product))
  • log.Fatal(http.ListenAndServe(":12345", router))
  • }

Controller 风格

  • package main
  • import (
  • "log"
  • "net/http"
  • "github.com/gookit/rux"
  • )
  • // News controller
  • type News struct {
  • }
  • func (n *News) AddRoutes(g *rux.Router) {
  • g.GET("/", n.Index)
  • g.POST("/", n.Create)
  • g.PUT("/", n.Edit)
  • }
  • func (n *News) Index(c *rux.Context) {
  • // Do something
  • }
  • func (n *News) Create(c *rux.Context) {
  • // Do something
  • }
  • func (n *News) Edit(c *rux.Context) {
  • // Do something
  • }
  • func main() {
  • router := rux.New()
  • // controller style
  • router.Controller("/news", new(News))
  • log.Fatal(http.ListenAndServe(":12345", router))
  • }

获取路由与生成请求URL

  • package main
  • import (
  • "log"
  • "net/http"
  • "net/url"
  • "github.com/gookit/rux"
  • )
  • func main() {
  • // Initialize a router as usual
  • router := rux.New()
  • router.GET(`/news/{category_id}/{new_id:\d+}/detail`, func(c *rux.Context) {
  • var u = make(url.Values)
  • u.Add("username", "admin")
  • u.Add("password", "12345")
  • b := rux.NewBuildRequestURL()
  • // b.Scheme("https")
  • // b.Host("www.mytest.com")
  • b.Queries(u)
  • b.Params(rux.M{"{category_id}": "100", "{new_id}": "20"})
  • // b.Path("/dev")
  • // println(b.Build().String())
  • println(c.Router().BuildRequestURL("new_detail", b).String())
  • // result: /news/100/20/detail?username=admin&password=12345
  • // get current route name
  • if c.MustGet(rux.CTXCurrentRouteName) == "new_detail" {
  • // post data etc....
  • }
  • }).NamedTo("new_detail", router)
  • // Use the HostSwitch to listen and serve on port 12345
  • log.Fatal(http.ListenAndServe(":12345", router))
  • }

相关项目

github 地址:https://github.com/gookit/rux

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐