V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
xnotepad
V2EX  ›  Go 编程语言

使用 go generics 自定义路由

  •  
  •   xnotepad ·
    caixw · 2022-03-17 08:59:21 +08:00 · 1761 次点击
    这是一个创建于 1007 天前的主题,其中的信息可能已经有所发展或是发生改变。

    自己写的库 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 行不到的代码就可以实现一个功能完备的路由功能。很适合作为框架的路由实现。

    5 条回复    2022-03-23 10:30:58 +08:00
    Oktfolio
        1
    Oktfolio  
       2022-03-17 09:06:38 +08:00
    借楼,我想不通为什么主流 Go Web 框架要用 :param 作为路径参数,有没有不是用 :param 的,实现谷歌的 /resource/name:customVerb 这种 URI 设计风格。
    xnotepad
        2
    xnotepad  
    OP
       2022-03-17 09:34:23 +08:00
    @Oktfolio 为解析简单一些吧。我更懒一些,直接用 /resource/{name:verb} 的形式,拿大括号中的内容就行。
    xnotepad
        3
    xnotepad  
    OP
       2022-03-17 09:53:09 +08:00
    #2 要实现 google 风格的话,/resource/{name:rule}:{verb:rule} 就可以了。
    BeijingBaby
        4
    BeijingBaby  
       2022-03-22 13:40:30 +08:00
    还是喜欢签名为 (w http.ResponseWriter, r *http.Request) 的库,和标准库切换没有成本。
    xnotepad
        5
    xnotepad  
    OP
       2022-03-23 10:30:58 +08:00
    @BeijingBaby 这个库的作用就是让用户可以自定义这个函数签名。不过默认提供了一个支持 ` (w http.ResponseWriter, r *http.Request)` 的实现:`Router`。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5126 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:38 · PVG 17:38 · LAX 01:38 · JFK 04:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.