Go1.22 新特性:终于增强 http.ServerMux 路由能力,将有更强的表现力!

大家好,我是煎鱼。

Go1.22 有一个比较重要的新特性,那就是基于提案《net/http: enhanced ServeMux routing》,增强了 http.ServerMux 的路由匹配能力。非常值得大家学习和关注。

本次的新特性主要是新增了 HTTP 方法和路径变量。

快速学习

在 Go 中,可以认为几乎所有的路由相关的库都会基于 net/http 或是兼容其 interface。否则容易脱离一个标准路线。

本文的主角 ServeMux,函数签名如下:

go 复制代码
type ServeMux
func NewServeMux() *ServeMux
func (mux *ServeMux) Handle(pattern string, handler Handler)
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

最简单的 Demo 如下:

go 复制代码
type apiHandler struct{}

func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}

func main() {
	mux := http.NewServeMux()
	mux.Handle("/api/", apiHandler{})
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		...
		fmt.Fprintf(w, "你好,煎鱼!)
	})
}

用法非常的简单和标准,就是路径和实现方法。

新提案

缘由

这是一个很少见的提案,居然没有显著的说明没有这个的缺陷或问题。说明大家在潜意识里已经是比较认可的,不需要额外解释。

原因应该是:net/http.ServeMux 所提供的路由功能过于的基础了。

因此路由使用上,很多人都不优先推荐使用 net/http,而是更推荐 gorilla/mux 等知名开源库作为基础库,提高实现的效率和产能。

本次新提案将会增加:模式匹配、路径变量的支持。

Go1.22 路由增强

匹配方法

模式匹配将支持以 HTTP 方法开头,后跟空格,如 GET /eddycjy 或 GET eddycjy.com/ 中。 带有方法的模式仅用于匹配具有该方法的请求。

对照到代码中,也就是 Go1.22 起,http.ServeMux 可以这么写:

go 复制代码
mux.HandleFunc("POST /eddycjy/create", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "脑子进煎鱼了!")
})

mux.HandleFunc("GET /eddycjy/update", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "煎鱼进脑子了...")
})
...

通配符

模式匹配将支持 {name} 或 {name...},例如:/b/{bucket}/o/{objectname...}。

该名称必须是有效的 Go 标识符和符合完整路径元素的标准。它们前面必须有斜杠,后面必须有斜杠或字符串末尾。例如:/b_{bucket} 不是有效的通配模式。

Go1.22 起,http.ServeMux 可以这么写:

go 复制代码
mux.HandleFunc("/eddycjy/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    fmt.Fprintf(w, "id 值为 %s", id)
})

mux.HandleFunc("/eddycjy/{path...}", func(w http.ResponseWriter, r *http.Request) {
    path := r.PathValue("path")
    fmt.Fprintf(w, "path 值为 %s", path)
})
...

优先级

单一的优先规则:

  1. 如果两个模式重叠(有一些共同的请求),那么更具体的模式优先。
  2. 如果 P1 符合 P2 请求的一个(严格)子集,也就是说:如果 P2 符合 P1 的所有请求及更多请求,那么 P1 就比 P2 更具体。
  3. 如果两者都不更具体,那么模式就会发生冲突。
  4. 这条规则有一个例外:如果两个模式发生冲突,而其中一个有 HOST ,另一个没有,那么有 HOST 的模式优先。

以下是图示参考:

具体的例子:

  • example.com/ 比 / 更具体,因为第一个仅匹配主机 example.com 的请求,而第二个匹配任何请求。
  • GET / 比 / 更具体,因为第一个仅匹配 GET 和 HEAD 请求,而第二个匹配任何请求。
  • /b/{bucket}/o/default 比 /b/{bucket}/o/{noun} 更具体,因为第一个仅匹配第四个元素是文字 "default" 的路径,而在第二个中,第四个元素可以是任何内容。

总结

今天我们分享了 Go1.22 对于 net/http 标注库中的 ServerMux 路由相关功能的增强。

Go 还是有在吸收第三方开源库的一些不错的地方的,就是慢了一些。这都 10 多年了...

文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blo... 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。

推荐阅读

相关推荐
用户40158233246213 小时前
对话一长,AI 就忘了你说过的话?Claude Code、Codex、Aider、WES Code 怎么压缩上下文
人工智能·go·ai编程
我的div丢了肿么办17 小时前
go语言抽离路由文件以及对路由进行分组
后端·go
孔令飞18 小时前
【OneX】OneX AI 工具安装、配置及功能介绍
云原生·go·ai编程
小满zs21 小时前
Go语言第十四章(文件操作)
后端·go
vipxieliang21 小时前
Go 1.24 工具链改进实战:工具依赖管理与 go vet 新分析器
后端·go
程序员爱钓鱼1 天前
Go 编程实战:Benchmark——基准测试、testing.B、benchmem、性能对比与代码优化实战
go·排序算法
Thinker QAQ2 天前
并发编程(十一):Shared Memory 与 Message Passing——关系与组合使用
java·python·go·并发编程·shared memory·message passing
喵个咪2 天前
GoWind Kanban 拆解:看板拖拽背后——LexoRank、乐观锁与尽力而为广播
后端·架构·go
喵个咪2 天前
GoWind OA 拆解:用 3000 行 Go 写一个够用的审批工作流引擎
后端·架构·go
喵个咪2 天前
GoWind Ledger 拆解:单式记账的余额一致性——confirm、补偿,以及没进事务的那些缝隙
后端·架构·go