go 1.22 增强 http.ServerMux 路由能力

之前

server

go 复制代码
func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Received request:", r.URL.Path)
		fmt.Fprintf(w, "Hello, client! You requested: %s\n", r.URL.Path)
	})

	log.Println("Server is running on http://localhost:8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe error: ", err)
	}
}

client

go 复制代码
func main() {
	url := "http://localhost:8080/some-path"

	// 创建HTTP GET请求
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal("HTTP GET error: ", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal("Error reading response body: ", err)
	}

	fmt.Println("Response from server:", string(body))
}

模式匹配优先级

如果两个模式重叠,那么更精确的模式优先。

如果 P1 符合 P2 请求的一个(严格)子集,P1 就比 P2 更精细

如果两者都不更具体,那么模式就会发生冲突

例外:

如果两个模式发生冲突,而其中一个有 HOST ,另一个没有,那么有 HOST 的模式优先。

example.com/ 比 / 更精细

因为第一个仅匹配主机 example.com 的请求,而第二个匹配任何请求

GET / 比 / 更精细

因为第一个仅匹配 GET 和 HEAD 请求,而第二个匹配任何请求

/b/{bucket}/o/default 比 /b/{bucket}/o/{noun} 更精细

第一个仅匹配第四个元素是文字 "default" 的路径,而在第二个中,第四个元素可以是任何内容

匹配方法

模式匹配将支持以 HTTP 方法开头,后跟空格,如 GET /demo 或 GET demo.com/ 中

带有方法的模式仅用于匹配具有该方法的请求

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

go 复制代码
mux.HandleFunc("POST /demo/create", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "demo create")
})

mux.HandleFunc("GET /demo/update", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "demo update")
})

通配符

模式匹配将支持 {name} 或 {name...}

例如:/b/{bucket}/o/{objectname...}

该名称必须是有效的 Go 标识符和符合完整路径元素的标准

它们前面必须有斜杠,后面必须有斜杠或字符串末尾

例如:/b_{bucket} 不是有效的通配模式

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

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

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

示例

server

go 复制代码
func main() {
	http.HandleFunc("/demo/{id}", func(w http.ResponseWriter, r *http.Request) {
		id := r.PathValue("id")
		fmt.Fprintf(w, "id %s\n", id)
		fmt.Fprintf(w, "Hello, client! You requested: %s\n", r.URL.Path)
	})

	log.Println("Server is running  on /demo/x")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe error: ", err)
	}
}

client

go 复制代码
func client() {
	url := "http://localhost:8080/demo/2?name=cucc"

	// 创建HTTP GET请求
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal("HTTP GET error: ", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal("Error reading response body: ", err)
	}

	fmt.Println("Response from server:\n", string(body))
}
相关推荐
念何架构之路2 小时前
zap WriteSyncer与Sink体系
云原生·golang
microrain4 小时前
权限改了,接口立刻生效,菜单要等重新登录:SagooIoT 权限体系的四道闸门
物联网·golang·开源·sagooiot
AIgorithmGEEK5 小时前
[Linux]HTTP 应用层协议全解(下篇)
linux·网络·网络协议·http·cookie·无连接·无状态
AIgorithmGEEK6 小时前
[Linux]HTTP 应用层协议全解(中篇)
linux·网络·网络协议·http
91刘仁德6 小时前
HTTPS 加密原理与 CA 数字证书:从对称加密到完整通信流程
网络·笔记·网络协议·http·https
大侠归来1 天前
C 与 Go 语言对比:从设计哲学到工程实践
java·c语言·golang
勇往直前plus1 天前
HTTPS 详解
网络协议·http·https
小小龙学IT1 天前
Go 语言内存管理与垃圾回收(GC)深度解析:从逃逸分析到性能调优适
golang·go1.19
wechatbot8881 天前
企业微信HTTP协议接口完整接入教程|全量消息收发 API 实战
网络协议·http·微信·企业微信·ai编程
web打印社区1 天前
Lodop 提示未安装或请升级:Chrome 里先分清该装哪套
开发语言·前端·javascript·chrome·websocket·http