使用 go generics 自定义路由

2022-03-17 08:59:21 +08:00
 xnotepad

自己写的库 https://github.com/issue9/mux 基于 go1.18 的范型功能,实现对路由处理函数签名的自定义。

type (
    Context struct {
        R *http.Request
        W http.ResponseWriter
        P mux.Params
    }

    Handler interface {
        Handle(*Context)
    }

    HandlerFunc func(*Context)

    Router         = mux.RouterOf[Handler]
    Prefix         = mux.PrefixOf[Handler]
    Resource       = mux.ResourceOf[Handler]
    Middleware     = mux.MiddlewareOf[Handler]
    Options        = mux.OptionsOf[Handler]
)

func (f HandlerFunc) Handle(c *Context) { f(c) }

func call(w http.ResponseWriter, r *http.Request, ps mux.Params, h Handler) {
    h.Handle(&Context{R: r, W: w, P: ps})
}

func NewRouter(name string, o Options) *Router {
    opt := &options{}
    for _, oo := range o {
        oo(opt)
    }
    return NewRouterOf[Handler](name, call, opt)
}

仅需 100 行不到的代码就可以实现一个功能完备的路由功能。很适合作为框架的路由实现。

1739 次点击
所在节点    Go 编程语言
5 条回复
Oktfolio
2022-03-17 09:06:38 +08:00
借楼,我想不通为什么主流 Go Web 框架要用 :param 作为路径参数,有没有不是用 :param 的,实现谷歌的 /resource/name:customVerb 这种 URI 设计风格。
xnotepad
2022-03-17 09:34:23 +08:00
@Oktfolio 为解析简单一些吧。我更懒一些,直接用 /resource/{name:verb} 的形式,拿大括号中的内容就行。
xnotepad
2022-03-17 09:53:09 +08:00
#2 要实现 google 风格的话,/resource/{name:rule}:{verb:rule} 就可以了。
BeijingBaby
2022-03-22 13:40:30 +08:00
还是喜欢签名为 (w http.ResponseWriter, r *http.Request) 的库,和标准库切换没有成本。
xnotepad
2022-03-23 10:30:58 +08:00
@BeijingBaby 这个库的作用就是让用户可以自定义这个函数签名。不过默认提供了一个支持 ` (w http.ResponseWriter, r *http.Request)` 的实现:`Router`。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/840922

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX