Golang 1.22于2024年2月6日发布。该版本应用了相当多的更新。我非常感兴趣的一件事是增强的路由模式。借助此功能,我们可以创建动态路由参数,而无需第三方库。让我们进一步探索。
问题
在 golang 中创建一个 http 服务器非常简单。例如,如下面的代码片段所示。
package main
import ( "fmt" "net/http" )
func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello from route /index") }
func main() { http.HandleFunc("/index", IndexHandler)
http.ListenAndServe(":8080", nil) }
|
当我们访问 localhost:8080/index 时,将收到来自路由 /index 的 Hello 响应。
正如你所看到的,在 IndexHandler 中会出现一些麻烦和问题,包括:
- (1) 如何验证 HTTP 方法(无需重复检查 HTTP 方法)?
- (2) 如何处理动态 URL 参数情况,如 /index/foo 或 index/bar?
解决方案:在Go 1.22 之前
要解决这个问题,最简单的办法就是使用现有的社区库。有很多 golang 库都支持这种方法,例如 mux、chi、echo 等等。例如,在 chi 中,你可以这样做:
package main
import ( "fmt" "net/http"
"github.com/go-chi/chi/v5" )
func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello from route /index") }
func DynamicHandler(w http.ResponseWriter, r *http.Request) { param := chi.URLParam(r, "param") fmt.Fprintf(w, "Hello from route /index/%s", param) }
func main() { r := chi.NewRouter()
r.Get("/index", IndexHandler) r.Get("/index/{param}", DynamicHandler) http.ListenAndServe(":3000", r)
|
有了这个
- (1) 我们不必在每个 http 处理程序中键入 if r.Method == "GET"。
- (2) 我们可以轻松获取请求的 url 参数。
进入 Go 1.22
在 Go 1.22 中,我们只需使用标准库就能解决之前的问题。下面是一个例子:
package main
import ( "fmt" "net/http" )
func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello from route /index") }
func DynamicHandler(w http.ResponseWriter, r *http.Request) { param := r.PathValue("param") fmt.Fprintf(w, "Hello from route /index/%s", param) }
func main() { http.HandleFunc("GET /index", IndexHandler) http.HandleFunc("GET /index/{param}", DynamicHandler)
http.ListenAndServe(":8080", nil) }
|
正如你所看到的,它看起来与现有库几乎一样。不同之处在于:
http 方法是在 url 路径之前定义的。要检索动态 url 参数的值,我们可以使用 r.PathValue。请注意,HTTP 方法区分大小写,因此 http 方法名称必须大写(GET,而不是 Get 或 get)。
结论
有了这个增强的路由模式,使用 golang 创建 http 服务器将变得更简单、更高效,因为标准库提供了两个重要的功能。当然,如果你想创建的 http 服务器具有复杂的功能,最好还是使用 golang 社区提供的网络框架/路由库。