Gin框架介紹
Gin是一個用Go語言編寫的web框架。它是一個類似於martini但擁有更好性能的API框架, 由於使用了httprouter,速度提高了近40倍。
中文文檔
Gin框架安裝與使用
安裝GIN
$ go get -u github.com/gin-gonic/gin
第一個Gin程序
package main
import "github.com/gin-gonic/gin"
func main() {
// 創建一個默認的路由引擎
engine := gin.Default()
// GET:請求方式;/hello:請求的路徑
// 當客戶端以GET方法請求/hello路徑時,會執行后面的匿名函數
engine.GET("/hello", func(context *gin.Context) {
//返回JSON格式的數據
context.JSON(200, gin.H{
"message": "Hello ares!",
})
})
// 啟動HTTP服務,默認在0.0.0.0:8080啟動服務
engine.Run()
}
-----------------
$curl 127.0.0.1:8080/hello
{"message":"Hello ares!"}
Gin網絡請求與路由處理
創建Engine
Engine被定義成一個結構體,默認可以使用gin.Default()和gin.New()創建。區別在於gin.Default()也適用gin.New()創建engine實例,但是會默認使用Logger和Recover中間件。
Logger是負責進行打印並輸出日志的中間件,方便開發者進行程序調試; Recovery中間件的作如果程序執行過程中遇到panc中斷了服務,則 Recovery會恢復程序執行,並返回服務器500內誤。通常情況下,我們使用默認的gin.Defaul創建 Engine實例。
Handle處理Get請求
附帶name默認值
engine := gin.Default()
//get,http://127.0.0.1:8080/hello?name=wx
engine.Handle("GET", "/hello", func(context *gin.Context) {
path := context.FullPath()
fmt.Println(path)
//獲取name參數,默認為ares
name := context.DefaultQuery("name", "ares")
fmt.Println(name)
context.Writer.Write([]byte("Hello " + name))
})
通過 Handle方法第一個參數指定處理GET類型的請求,解析的接囗是/ hello。
Context是gin框架中封裝的一個結構體,這是gn框架中最重要,最基礎的一個結構體對象。該結構體可以提供我們操作請求,處理請求,獲取數據等相關的操作,通常稱之為上下文對象,簡單說為我們提供操作環境可以通過 context. Query和 context. DefaultQuery獲取GET請求攜帶的參數。
engine可以直接解析方法,按照以下方式。
//get,http://127.0.0.1:8080/hello?name=wx
engine.GET("/hello", func(context *gin.Context) {
fmt.Println(context.FullPath())
name := context.Query("name")
fmt.Println(name)
context.Writer.Write([]byte("hello" + name))
})
Handle處理Post,Delete請求
engine := gin.Default()
engine.POST("/login", func(context *gin.Context) {
fmt.Println(context.FullPath())
username, exist := context.GetPostForm("username")
if exist {
fmt.Println(username)
}
context.Writer.Write([]byte("hello" + username))
})
engine.DELETE("/user/:id", func(context *gin.Context) {
fmt.Println(context.FullPath())
//獲取id
userID := context.Param("id")
fmt.Println(userID)
context.Writer.Write([]byte("刪除id" + userID))
})
engine.Run()
Gin表單實體綁定
使用 PostForm這種單個獲取屬性和字段的方式,代碼量較多,需要一個一個屬性進行獲取。而表單數據的提交,往往對應着完整的數據結構體定義,其中對應着表單的輸入項。gin框架提供了數據結構體和表單提交數據綁定的功能,提高表單數據獲取的效率。
ShouldBindQuery(Get)
ShouldBindQuery可以實現Get方式的數據請求綁定。
type Student struct {
Name string `form:"name"`
Classes string `form:"classes"`
}
func main() {
engine := gin.Default()
//請求數據綁定,定義結構體
engine.GET("/hello", func(context *gin.Context) {
fmt.Println(context.FullPath())
var student Student
err := context.ShouldBindQuery(&student)
if err != nil {
log.Fatal(err.Error())
return
}
fmt.Println(student.Classes)
fmt.Println(student.Name)
context.Writer.Write([]byte("hello" + " " + student.Name + " " + student.Classes))
})
engine.Run()
}

ShouldBind(Post)
ShouldBind可以實現Post方式的數據請求綁定。
type Resiter struct {
Name string `form:"name"`
Password string `form:"password"`
}
func main() {
engine := gin.Default()
engine.POST("/register", func(context *gin.Context) {
fmt.Println(context.FullPath())
var resiter Resiter
err := context.ShouldBind(&resiter)
if err != nil {
log.Fatal(err.Error())
return
}
fmt.Println(resiter.Name)
fmt.Println(resiter.Password)
context.Writer.Write([]byte(resiter.Name + " " +"resiter"))
})
engine.Run()
}

BindJSON(處理json格式數據)
結構體格式務必正確。
type Person struct {
Name string `form:"name"`
Age int `form:"age"`
}
func main() {
engine := gin.Default()
engine.POST("/add", func(context *gin.Context) {
fmt.Println(context.FullPath())
var person Person
err := context.BindJSON(&person)
if err != nil {
log.Fatal(err.Error())
return
}
fmt.Println("name:", person.Name)
fmt.Println("age:", person.Age)
context.Writer.Write([]byte("添加" + " " + person.Name))
})
engine.Run()
}

Gin多數據格式返回請求結果
[]byte切片類型
func main() {
engine := gin.Default()
engine.GET("/byte", func(context *gin.Context) {
fmt.Println(context.FullPath())
fullpath := context.FullPath()
context.Writer.Write([]byte(fullpath))
})
engine.Run()
}
Json類型
項目開發中,json格式使用更為普遍。
Gin為了方便開發者更方便的使用該框架進行項目開發,直接支持將返回數據組裝成JSON格式進行返回。
Gin框架中的context包含的JsoN方法可以將結構體類型的數據轉換成JSON格式的結構化數據,然后返回給客戶端。
type Stu struct {
Name string
Id int
Extra string
}
func main() {
engine := gin.Default()
//map類型
//調用JSON將map類型數據轉換為json格式返回給前端,第一個參數200表示設置請求返回的狀態碼,和http請求狀態碼一樣
engine.GET("/hellojson", func(context *gin.Context) {
fmt.Println(context.FullPath())
fullpath := context.FullPath()
context.JSON(200, map[string]interface{}{
"code": 1,
"msg": "ok",
"date": fullpath,
})
})
//結構體類型
engine.GET("/helloStruct", func(context *gin.Context) {
fmt.Println(context.FullPath())
fullpath := context.FullPath()
var stu Stu
stu.Name = "ares"
stu.Id = 1
stu.Extra = fullpath
context.JSON(200, &stu)
})
engine.Run()
}
------------------------
$ curl 127.0.0.1:8080/hellojson
{"code":1,"date":"/hellojson","msg":"ok"}
$ curl 127.0.0.1:8080/helloStruct
{"Name":"ares","Id":1,"Extra":"/helloStruct"}
HTML模板
Gin框架還支持返回HTML格式的數據,可以直接渲染HTML頁面。需要將靜態資源路徑設置正確才會生效。
func main() {
engine := gin.Default()
//加載html路徑
engine.LoadHTMLGlob("./html/*")
//engine.LoadHTMLGlob("../html/*")
//加載靜態資源路徑
engine.Static("/image", "./image")
engine.GET("/html", func(context *gin.Context) {
fullpath := "路徑" + context.FullPath()
fmt.Println(fullpath)
context.HTML(http.StatusOK, "index.html", gin.H{
"fullpath": fullpath,
})
})
engine.Run()
}
html頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GIN ares</title>
</head>
<body>
<h1>GIN</h1>
{{.fullpath}}
<br>
<img src="../image/shui.jpeg">
</body>
</html>

使用路由組分類處理請求
實際項目中,均為模塊化開發,同一模塊內的功能接口廟會有相同的接口前綴,如下:
注冊:127.0.0.1:8080/user/register
登錄:127.0.0.1:8080/user/login
刪除:127.0.0.1:8080/user/delete
GIN框架中可使用路由組來實現路由分類。
//定義user結構體
type User struct {
Name string `form:"name"`
}
//簡潔main函數,把登錄handle單獨拿出來
func loginHandle(context *gin.Context) {
fullpath := "登錄" + context.FullPath()
fmt.Println(fullpath)
var user User
err := context.ShouldBind(&user)
if err != nil {
log.Fatal(err.Error())
return
}
context.Writer.Write([]byte(fullpath + " " + user.Name))
}
//刪除handle
func deleteHandle(context *gin.Context) {
fullpath := "刪除" + context.FullPath()
ID := context.Param("id")
fmt.Println(fullpath + " " + ID)
context.Writer.Write([]byte(fullpath + " " + ID))
}
func main() {
engine := gin.Default()
routeGroup := engine.Group("/user")
//注冊
routeGroup.POST("/register", func(context *gin.Context) {
fullpath := "注冊" + context.FullPath()
fmt.Println(fullpath)
context.Writer.Write([]byte(fullpath))
})
//登錄
routeGroup.POST("/login", loginHandle)
//刪除
routeGroup.POST("/delete", deleteHandle)
engine.Run()
}