Golang GinWeb框架-快速入門/參數(shù)解析
Gin是Golang寫的Web框架, 功能類似另一個Go框架Martini(暫停維護(hù)https://github.com/go-martini/martini), Gin內(nèi)部使用定制版本的httprouter(一款輕量級高性能HTTP請求路由器,或叫多路復(fù)用器), 速度是Martini的40倍, Gin擁有強大的性能,高效率,以及可擴(kuò)展性, 所以趕快用起來吧!
安裝
Go版本要求: Go1.12及以上
1. 執(zhí)行以下命令安裝最新版本Gin
- $ go get -u github.com/gin-gonic/gin
 
2. 在你的代碼中導(dǎo)入
- import "github.com/gin-gonic/gin"
 
3. (可選)導(dǎo)入net/http包, 如果你要使用其中的常量,比如http.StatusOK,則需要導(dǎo)入
- import "net/http"
 
快速開始
編寫main.go,寫入以下代碼并執(zhí)行g(shù)o run main.go, 訪問http://localhost:8080/ping, 就可以得到響應(yīng)消息{"message": "pong"}
- package main
 - import "github.com/gin-gonic/gin"
 - func main() {
 - r := gin.Default() //創(chuàng)建默認(rèn)Gin引擎Engine,內(nèi)部默認(rèn)開啟了日志和異常恢復(fù)中間件
 - r.GET("/ping", func(c *gin.Context) {
 - c.JSON(200, gin.H{
 - "message": "pong",
 - })
 - })
 - r.Run() //默認(rèn)在localhost:8080監(jiān)聽
 - }
 
基準(zhǔn)測試

測試結(jié)果說明:
Benchmark name: 基準(zhǔn)測試項
第(1)列:在固定時間內(nèi)完成的重復(fù)次數(shù), 值越大性能好
第(2)列:執(zhí)行單次重復(fù)任務(wù)消耗的納秒數(shù), 單位ns/op, 值越低越好
第(3)列:執(zhí)行單次重復(fù)任務(wù)消耗的堆內(nèi)存字節(jié)數(shù), 單位B/op, 值越低越好
第(4)列:每個重復(fù)任務(wù)平均分配內(nèi)存的次數(shù), 單位allocs/op, 值越低越好
Gin V1穩(wěn)定版特性
- 零內(nèi)存分配的路由器
 - 仍然是最快的http路由器和框架
 - 完整的單元測試
 - 嚴(yán)格測試
 - API版本凍結(jié),新發(fā)布的版本對你原來的代碼兼容
 
使用jsoniter編譯
jsoniter(https://github.com/json-iterator/go)是一個高性能可以替代Golang標(biāo)準(zhǔn)庫encoding/json并且完全兼容的包
Gin默認(rèn)使用encoding/json包,但是你可以使用以下tags修改為jsoniter重新編譯源碼
- go build -tags=jsoniter .
 
API示例
你可以訪問源碼,查看更多接口示例代碼:https://github.com/gin-gonic/examples
使用GET,POST,PUT,PATCH,DELETE,OPTIONS
- func main() {
 - // Creates a gin router with default middleware:
 - // logger and recovery (crash-free) middleware
 - router := gin.Default()
 - router.GET("/someGet", getting)
 - router.POST("/somePost", posting)
 - router.PUT("/somePut", putting)
 - router.DELETE("/someDelete", deleting)
 - router.PATCH("/somePatch", patching)
 - router.HEAD("/someHead", head)
 - router.OPTIONS("/someOptions", options)
 - // By default it serves on :8080 unless a
 - // PORT environment variable was defined.
 - router.Run()
 - // router.Run(":3000") for a hard coded port 指定端口
 - }
 
路徑參數(shù)
- func main() {
 - router := gin.Default()
 - // This handler will match /user/john but will not match /user/ or /user
 - //以下路由只會匹配/user/用戶名, 不會匹配/user/或者/user
 - router.GET("/user/:name", func(c *gin.Context) {
 - name := c.Param("name") //使用Param方法從路徑中獲取參數(shù)
 - c.String(http.StatusOK, "Hello %s", name)
 - })
 - // However, this one will match /user/john/ and also /user/john/send
 - // If no other routers match /user/john, it will redirect to /user/john/
 - // 以下帶冒號:和帶星號*組成的路由可以匹配/user/用戶名/或/user/用戶名/動作,如果/user/用戶名沒有匹配到其他路由,它會自動重定向到/user/用戶名/進(jìn)行匹配
 - router.GET("/user/:name/*action", func(c *gin.Context) {
 - name := c.Param("name")
 - action := c.Param("action")
 - message := name + " is " + action
 - c.String(http.StatusOK, message)
 - })
 - // For each matched request Context will hold the route definition
 - // 請求上下文request Context會保存所有匹配上的路由定義到c.FullPath()方法
 - router.POST("/user/:name/*action", func(c *gin.Context) {
 - c.FullPath() == "/user/:name/*action" // true
 - })
 - router.Run(":8080")
 - }
 
查詢字符串參數(shù)
- func main() {
 - router := gin.Default()
 - // Query string parameters are parsed using the existing underlying request object.
 - // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
 - // 發(fā)送測試請求:/welcome?firstname=Jane&lastname=Doe
 - router.GET("/welcome", func(c *gin.Context) {
 - firstname := c.DefaultQuery("firstname", "Guest") //如果沒有獲取到該鍵值,則使用第二個參數(shù)作為默認(rèn)值
 - lastname := c.Query("lastname")
 - //上一行的完整寫法:c.Request.URL.Query().Get("lastname")
 - c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
 - })
 - router.Run(":8080")
 - }
 
URL編碼的多種數(shù)據(jù)類型組成的表單請求
請求內(nèi)容類型為:application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded
- package main
 - import "github.com/gin-gonic/gin"
 - func main() {
 - router := gin.Default()
 - // 模擬提交表單:curl -XPOST http://localhost:8080/form_post -d "message=消息&nick=昵稱"
 - router.POST("/form_post", func(c *gin.Context) {
 - message := c.PostForm("message")
 - nick := c.DefaultPostForm("nick", "anonymous")
 - c.JSON(200, gin.H{
 - "status": "posted",
 - "message": message,
 - "nick": nick,
 - })
 - })
 - router.Run(":8080")
 - }
 - //返回結(jié)果: {"message":"消息","nick":"昵稱","status":"posted"}
 
查詢和提交Post表單相結(jié)合
- package main
 - import (
 - "fmt"
 - "github.com/gin-gonic/gin"
 - )
 - func main() {
 - router := gin.Default()
 - router.POST("/post", func(c *gin.Context) {
 - id := c.Query("id")
 - page := c.DefaultQuery("page", "0")
 - name := c.PostForm("name")
 - message := c.PostForm("message")
 - fmt.Printf("id: %s; page: %s; name: %s; message: %s\n", id, page, name, message)
 - c.JSON(200, gin.H{
 - "id": id,
 - "page": page,
 - "name": name,
 - "message": message,
 - })
 - })
 - router.Run(":8080")
 - }
 
模擬發(fā)送請求:
- curl -XPOST http://localhost:8080/post?id=1234&page=1 -d "name=manu&message=this_is_great"
 
返回結(jié)果:
- {"id":"1234","message":"this_is_great","name":"manu","page":"1"}
 
以Map映射作為查詢字符串或Post表單參數(shù)
- func main() {
 - router := gin.Default()
 - router.POST("/post", func(c *gin.Context) {
 - ids := c.QueryMap("ids") //獲取查詢參數(shù)中的Map
 - names := c.PostFormMap("names") //獲取Post表單中的Map
 - fmt.Printf("ids: %v; names: %v\n", ids, names)
 - })
 - router.Run(":8080")
 - }
 
- 模擬請求:
 - curl -XPOST http://localhost:8080/post?ids[a]=1234&ids[b]=hello -d "names[first]=thinkerou&names[second]=tianou"
 - 打印結(jié)果:
 - ids: map[a:1234 b:hello]; names: map[first:thinkerou second:tianou]
 
參考文檔
Gin官方倉庫:https://github.com/gin-gonic/gin
















 
 
 







 
 
 
 