前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go1.22来了!还需要HTTP框架吗?

Go1.22来了!还需要HTTP框架吗?

原创
作者头像
盐咔咔
发布2024-04-24 22:34:58
1040
发布2024-04-24 22:34:58

在Go语言原生的HTTP路由中大家是否注意到过功能不是很完善,比如需要硬编码区分GET还是POST请求,在Go 1.22中对Go的HTTP路由做了一定程度的增强,这都要源于一个提案:net/http: enhanced ServeMux routing(https://github.com/golang/go/issues/61410

在这个提案中提到了Go语言的路由应该变为:

代码语言:go
复制
GET example.com/

或者:

代码语言:go
复制
GET /foo

再或者:

代码语言:go
复制
GET example.com/foo

可以抽象为以下语义分配路由:

代码语言:shell
复制
[METHOD] [HOST]/[PATH]

解释:

  • METHOD:要为其执行分配的处理程序的请求方式,如GET、PUT、POST等。
  • HOST:要使用处理程序的主机名。
  • PATH:要将处理程序映射到的 Request 路径。

提案中还提到,其中一种模式比另一种模式更具体:

  • example.com// 更具体,因为第一个仅匹配与主机 example.com 的请求,而第二个匹配任何请求。
  • GET // 更具体,因为第一个只匹配 GET 和 HEAD 请求,而第二个匹配任何请求。
  • HEAD /GET / 更具体,因为第一个只匹配 HEAD 请求,而第二个同时匹配 GET 和 HEAD 请求。
  • /b/{bucket}/o/default/b/{bucket}/o/{noun} 更具体,因为第一个元素仅匹配第四个元素是文本“默认”的路径,而在第二个元素中,第四个元素可以是任何元素。

下面我们用代码对比下:

在1.22版本前的Go语言原生HTTP路由中,如果要区分GET和POST请求,我们需要这样:

代码语言:go
复制
func OriginalHttpService() {
	mux := http.NewServeMux()

	mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			_, _ = w.Write([]byte("Hello, This is GET method. [Go]"))
		case http.MethodPost:
			_, _ = w.Write([]byte("Hello, This is POST method. [Go]"))
		}
	})

	_ = http.ListenAndServe(":8801", mux)
}

如果不使用原生的HTTP包,我们可以用Gin框架,它就变成了这样:

代码语言:go
复制
func GinHttpService() {
	engine := gin.Default()

	engine.GET("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, "Hello, This is GET method. [Gin]")
	})
	engine.POST("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, "Hello, This is POST method. [Gin]")
	})

	_ = engine.Run(":8802")
}

如果到了Go1.22,我们就可以不使用框架实现这个功能:

代码语言:go
复制
func Go22NewHttpService() {
	mux := http.NewServeMux()

	mux.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("Hello, This is GET method. [Go 1.22]"))
	})
	mux.HandleFunc("POST /hello", func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("Hello, This is POST method. [Go 1.22]"))
	})

	_ = http.ListenAndServe(":8803", mux)
}

是不是觉得优雅了许多~

除此之外,新版本还支持了Restful风格的API,比如:

代码语言:go
复制
func Go22RestfulApi() {
	mux := http.NewServeMux()

	mux.HandleFunc("GET /hello/{name}", func(w http.ResponseWriter, r *http.Request) {
		name := r.PathValue("name")
		resp := fmt.Sprintf("Hello %s, This is GET method.", name)
		_, _ = w.Write([]byte(resp))
	})

	_ = http.ListenAndServe(":8803", mux)
}

在Path重叠的情况下,Go官方还提供了优先级的解释,比如 /posts/latest/posts/{id}在同一个HTTP服务中,会以更具体的作为优先,显然 /posts/latest/posts/{id}更具体,可以参考:https://go.dev/blog/routing-enhancements会有更详细的说明

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档