Go 1.22中HTTP包更新
每当我在网上遇到讨论或被问到使用哪个包在 Go 中创建 HTTP 服务器时,我的答案都是一致的。这实际上取决于您计划构建的 HTTP 服务的复杂性,但我始终建议net/http从标准包开始。
Go 语言拥有令人印象深刻的标准库,net/http是其实力的一个突出例子。随着 1.22 版本的发布,它变得更好了。
标准库问题是什么?
我是使用net/http简单服务的大力倡导者。然而,我知道,随着您的项目不断发展,您开始处理多个端点(每个端点都有自己的参数集并需要处理各种 HTTP 方法),事情可能会变得有点混乱。曾经整洁的 HTTP 处理程序开始变得像一个杂乱的房间,充满了重复的代码,并且变得有点难以导航。
func handlerUser (w http.ResponseWriter, r *http.Request) { |
现在,在管理单个端点的各种 HTTP 方法时,您可能会发现自己渴望像 Chi 或 Echo 这样简单的框架。这些软件包允许你为每种 HTTP 方法指定特定的处理程序,从而简化代码。不过,坚持使用标准的 net/http 包意味着你的处理程序本身需要容纳所有允许的方法,这可能会变得有点繁琐,如上图所示。
此外,处理路径参数还带来了另一层复杂性。如果没有更复杂框架的内置支持,你就只能采用变通方法。使用 http.StripPrefix 或使用 strings.TrimPrefix 手动修剪路径前缀等技巧就变得很有必要。这种方法有点临时抱佛脚,需要额外的代码和精力,才能完成使用专门路由库时相对简单的工作。
1.22版本的变化
处理多个 HTTP 方法和提取路径参数可能会让人觉得有点麻烦,但 Go 1.22 已经解决了这个问题。最新更新为 ServeMux 处理程序引入了增强的路由功能,使这些任务不再令人头疼。
现在,你可以在注册处理程序时直接指定 HTTP 方法,如 POST 或 GET。更令人印象深刻的是在 URL 模式中引入了通配符。这意味着您可以定义类似 /orders/{id} 这样的模式来匹配 URL 路径的特定段落,而这一功能以前需要第三方路由器或一些自定义解析逻辑。
从这些路径段中读取实际值也很简单。只需使用新的 Request.PathValue 方法即可。这一新增功能大大简化了动态路由所需的代码,使更复杂的网络应用程序的开发更顺畅、更直观。
mux.HandleFunc("GET /orders", func(w http.ResponseWriter, r *http.Request) {"GET /orders", func(w http.ResponseWriter, r *http.Request) { |
测试端点变得更容易了。
$ curl localhost:8080/orders8080/orders |
不过,并非每个端点都允许使用每种方法。如果您尝试使用不支持的方法,比如本例中的 DELETE:
$ curl -X DELETE localhost:8080/orders/2
Method Not Allowed
您将得到明确的回复:方法不允许。该响应可帮助您快速了解您试图执行的操作不允许该端点执行。
新的 {$} 功能
此外,新的通配符功能(以 {$} 标记)改变了 URL 模式的匹配方式,可以精确到尾部的斜线。在过去,像"/"这样的通配符就像一个 "万金油",可以拦截任何以"/"开头且没有定义其他通配符的路径。因此,"/"和"/this/does/not/exist "会无意中出现在同一个地方。
以下是一些开发人员使用的简单变通方法,可以同时优雅地管理主页和未识别的路径:
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {"/", func(w http.ResponseWriter, req *http.Request) { |
有了新的 {$} 功能,精确匹配就变得简单易行了。下面是使用方法:
mux.HandleFunc("/{$}", func(w http.ResponseWriter, r *http.Request) {"/{$}", func(w http.ResponseWriter, r *http.Request) { |