Go 語(yǔ)言高性能 Web 框架 Gin 框架路由和請(qǐng)求參數(shù)的使用方式
1.介紹
使用 Web 框架,可以在開發(fā)項(xiàng)目時(shí)更高效。Web 框架一般會(huì)支持基礎(chǔ)功能,比如路由、處理請(qǐng)求參數(shù)、渲染返回結(jié)果、中間件等。
本文我們介紹一款輕量級(jí) Web 框架 Gin 框架。
示例代碼:
package main
import "github.com/gin-gonic/gin"
func main() {
 r := gin.Default()
 r.GET("/ping", func(c *gin.Context) {
  c.JSON(200, gin.H{
   "message": "pong",
  })
 })
 r.Run()
}輸出結(jié)果:
curl -s http://127.0.0.1:8080/ping | jq
{
  "message": "pong"
}閱讀上面這段代碼,我們導(dǎo)入三方庫(kù) github.com/gin-gonic/gin,使用 gin.Default() 函數(shù)創(chuàng)建一個(gè)使用 Logger 和 Recovery 中間件的 Engine 實(shí)例(框架實(shí)例)。
然后使用 r.GET() 方法創(chuàng)建一個(gè)處理器,實(shí)際上 r.GET() 是 r.Handle() 的快捷方式。
最后,使用 r.Run() 方法(默認(rèn)監(jiān)聽地址 0.0.0.0:8080)綁定處理器到 http.Server,并開始監(jiān)聽和處理 http 請(qǐng)求,實(shí)際上 r.Run() 方法是 http.ListenAndServe() 函數(shù)的快捷方式。
2.路由
注冊(cè)路由
使用 Gin 框架注冊(cè)路由,調(diào)用框架實(shí)例的方法即可,Gin 框架提供 Handle() 方法,可以方便我們注冊(cè)任意 HTTP 方法的路由,示例代碼:
package main
import "github.com/gin-gonic/gin"
func main() {
 r := gin.Default()
 r.Handle("GET", "/ping", func(c *gin.Context) {
  c.JSON(200, gin.H{
   "message": "pong",
  })
 })
 r.Run()
}閱讀上面這段代碼,我們可以發(fā)現(xiàn) r.Handle() 方法接收 3 個(gè)參數(shù),第一個(gè)是 HTTP方法,第二個(gè)是路徑,第三個(gè)是處理器函數(shù)。
Gin 框架還提供了一些 HTTP 方法的快捷方式,例如:r.GET()、 r.POST()、r.DELETE()、r.PATCH()、r.PUT()、r.OPTIONS()、r.HEAD()。
此外,Gin 框架還提供了一個(gè)可以匹配所有 HTTP 方法的快捷方式,r.Any(),和一個(gè)可以匹配指定 HTTP 方法的快捷方式,r.Match()。
3.請(qǐng)求參數(shù)
接下來(lái),我們介紹 Gin 框架怎么接收請(qǐng)求參數(shù)。我們按照請(qǐng)求參數(shù)的格式,分別介紹各種格式的請(qǐng)求參數(shù)的接收方式。
請(qǐng)求字符串
請(qǐng)求字符串(queryString)是請(qǐng)求地址中英文問(wèn)號(hào) ? 后面的參數(shù),例如:
http://127.0.0.1:8080/user_info?username=frank
示例代碼:
HTTP 方法是 GET
package main
import "github.com/gin-gonic/gin"
func main() {
 r := gin.Default()
 r.GET("/user_info", GetUserInfo)
 r.Run()
}
func GetUserInfo(c *gin.Context) {
 userName := c.Query("username")
 c.JSON(200, gin.H{
  "username": userName,
 })
}輸出結(jié)果:
curl -s http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}Form 表單
HTTP 方法是 POST
package main
import "github.com/gin-gonic/gin"
func main() {
 r := gin.Default()
 r.POST("/user_info", PostUserInfo)
 r.Run()
}
func PostUserInfo(c *gin.Context) {
 userName := c.PostForm("username")
 c.JSON(200, gin.H{
  "username": userName,
 })
}輸出結(jié)果:
curl -s -X POST -d "username=frank" http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}JSON 字符串
以上示例代碼,都是使用默認(rèn) Content-Type Content-Type:application/x-www-form-urlencoded,當(dāng) Content-Type:application/json 時(shí),我們需要使用 c.GetRawData() 方法接收請(qǐng)求參數(shù),示例代碼:
package main
import (
 "encoding/json"
 "github.com/gin-gonic/gin"
)
func main() {
 r := gin.Default()
 r.POST("/user_info", JsonUserInfo)
 r.Run()
}
func JsonUserInfo(c *gin.Context) {
 // 定義 struct 或 map
 var m map[string]interface{}
 b, _ := c.GetRawData()
 _ = json.Unmarshal(b, &m)
 c.JSON(200, gin.H{
  "username": m["username"],
 })
}輸出結(jié)果:
curl -s -H "Content-Type: application/json" -X POST -d '{"username":"frank"}' http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}以上幾種方式,是我們開發(fā)項(xiàng)目時(shí)比較常用的方式,但是,我們?cè)谑褂靡陨蠋追N方式時(shí),需要事先約定 Content-Type。
通用方式
所以 Gin 框架還有另外一種接收請(qǐng)求參數(shù)的方式,也就是使用 c.ShouldBind() 方法。
它可以通過(guò)檢查 HTTP Method 和 Content-Type 的值,自動(dòng)將 quertString、form 表單、json 和 xml 的值解析到 struct。
示例代碼:
package main
import (
 "encoding/json"
 "github.com/gin-gonic/gin"
)
func main() {
 r := gin.Default()
 r.POST("/user_info", ShouldBindUserInfo)
 r.Run()
}
type UserInfo struct {
 Username string `form:"username" json:"username" xml:"username"`
}
func ShouldBindUserInfo(c *gin.Context) {
 var userInfo UserInfo
 _ = c.ShouldBind(&userInfo)
 c.JSON(200, gin.H{
  "username": userInfo.Username,
 })
}輸出結(jié)果:
// application/json
curl -s -H "Content-Type: application/json" -X POST -d '{"username":"frank"}' http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}
// application/xml
curl -s -H "Content-Type: application/xml" -X POST -d "<user_info><username>frank</username></user_info>" http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}
// application/x-www-form-urlencoded
curl -s -X POST -d "username=frank" http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}
// HTTP Method GET
curl -s http://127.0.0.1:8080/user_info\?username\=frank | jq
{
  "username": "frank"
}需要注意的是,自定義結(jié)構(gòu)體的標(biāo)簽,不要漏掉。否則,將無(wú)法將請(qǐng)求參數(shù)的值解析到結(jié)構(gòu)體中。
4.總結(jié)
本文我們介紹 Go 語(yǔ)言高性能 Web 框架 Gin 框架的路由和請(qǐng)求參數(shù)的一般使用方式,建議讀者朋友們動(dòng)手運(yùn)行文章中的示例代碼。
參考資料
[1] Gin 文檔: https://gin-gonic.com/zh-cn/docs/
[2] Gin 源碼: https://github.com/gin-gonic/gin/blob/master/context.go















 
 
 


















 
 
 
 