Gin 框架入門
一、響應數據
JSON 響應
在 Web 開發中,JSON 是一種常用的數據交換格式。Gin 提供了簡便的方法來響應 JSON 數據。
package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/json", func(c *gin.Context) {c.JSON(200, gin.H{"message": "hello json",})})r.Run(":8080")
}
在上述代碼中,通過 c.JSON()
方法,我們可以指定狀態碼和要響應的 JSON 數據,gin.H
是一個快捷的 map 類型,方便我們快速構建 JSON 響應內容。
文件響應
當需要響應文件時,Gin 也提供了簡單易用的方法。
r.GET("/file", func(c *gin.Context) {c.File("./example.txt")
})
這里的 c.File()
方法直接將指定路徑的文件響應給客戶端。
HTML 響應
對于 HTML 頁面的響應,Gin 同樣有相應的方法。
r.LoadHTMLFiles("index.html") // 加載 HTML 模板文件r.GET("/html", func(c *gin.Context) {c.HTML(200, "index.html", gin.H{"title": "Gin HTML 響應示例",})
})
我們先通過 LoadHTMLFiles()
方法加載 HTML 模板文件,然后在路由處理函數中使用 c.HTML()
方法來渲染 HTML 頁面,還可以將數據傳遞給模板進行動態展示。
重定向
重定向在 Web 開發中也經常用到,Gin 支持多種重定向方式。
r.GET("/redirect", func(c *gin.Context) {c.Redirect(302, "https://example.com")
})
上述代碼實現了臨時重定向,使用 c.Redirect()
方法指定重定向的狀態碼和目標 URL。
二、請求參數處理
查詢參數
查詢參數通常包含在 URL 的查詢字符串中,我們可以通過 c.Query()
來獲取單個查詢參數,通過 c.DefaultQuery()
來獲取帶有默認值的查詢參數。
r.GET("/query", func(c *gin.Context) {name := c.Query("name")age := c.DefaultQuery("age", "18")c.String(200, "name: %s, age: %s", name, age)
})
當我們訪問 /query?name=John
時,輸出為 name: John, age: 18
。
動態參數
動態參數可以定義在路由路徑中,通過 :paramName
的形式指定,然后在處理函數中使用 c.Param()
獲取。
r.GET("/user/:id", func(c *gin.Context) {id := c.Param("id")c.String(200, "User ID: %s", id)
})
當我們訪問 /user/123
時,輸出為 User ID: 123
。
表單參數
對于表單提交的數據,可以使用 c.PostForm()
來獲取單個表單參數,使用 c.DefaultPostForm()
來獲取帶有默認值的表單參數。
r.POST("/form", func(c *gin.Context) {username := c.PostForm("username")password := c.DefaultPostForm("password", "123456")c.String(200, "Username: %s, Password: %s", username, password)
})
當表單提交包含 username
和 password
字段時,就能正確獲取并響應。
原始參數
對于原始的請求體數據,可以通過 c.Request.Body
來獲取。
r.POST("/raw", func(c *gin.Context) {body, _ := ioutil.ReadAll(c.Request.Body)c.String(200, "Raw data: %s", body)
})
這樣就能讀取整個請求體的原始數據。
三、綁定參數
JSON 參數和 header 參數
Gin 支持使用綁定(binding)來將請求參數自動映射到結構體中。
type User struct {Username string `json:"username" binding:"required"`Password string `json:"password" binding:"required"`
}r.POST("/bind", func(c *gin.Context) {var user Userif err := c.ShouldBindJSON(&user); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}c.JSON(200, gin.H{"username": user.Username,"password": user.Password,})// 獲取 header 參數authHeader := c.Request.Header.Get("Authorization")c.JSON(200, gin.H{"auth_header": authHeader})
})
在 ShouldBindJSON()
方法中,會根據結構體中的標簽(如 json
和 binding
)來解析 JSON 參數并進行驗證。通過 c.Request.Header.Get()
可以獲取請求頭中的參數。
綁定內置規則
Gin 提供了一些內置的驗證規則,如 required
表示字段是必填的,min
和 max
可以限制字段的長度等。
type Product struct {Name string `json:"name" binding:"required"`Price uint `json:"price" binding:"required,gt=0"`
}
這里對 Price
字段設置了 required
和 gt=0
(大于 0)的驗證規則。
綁定錯誤信息
當綁定驗證不通過時,Gin 會返回相應的錯誤信息,我們可以在處理函數中捕獲并返回給客戶端。
if err := c.ShouldBindJSON(&user); err != nil {c.JSON(400, gin.H{"error": err.Error()})return
}
會將詳細的錯誤信息返回給客戶端,告知哪些字段驗證不通過及其原因。
定義驗證器
我們還可以自定義驗證器來滿足特定的驗證需求。
import "github.com/go-playground/validator/v10"func init() {validate := validator.New()validate.RegisterValidation("mycustom", func(fl validator.FieldLevel) bool {return fl.Field().String() == "custom"})
}type Custom struct {Value string `json:"value" binding:"mycustom"`
}
在 RegisterValidation()
方法中注冊自定義的驗證規則,然后在結構體標簽中使用該規則。
四、路由
Gin 的路由使用簡單直觀,通過 GET
、POST
等方法來定義不同 HTTP 方法的路由。
r.GET("/index", indexHandler)
r.POST("/submit", submitHandler)
我們還可以使用通配符路由來匹配多個路徑。
r.GET("/files/*filepath", func(c *gin.Context) {filepath := c.Param("filepath")c.String(200, "File path: %s", filepath)
})
當訪問 /files/images/avatar.png
時,filepath
為 images/avatar.png
。
五、中間件
局部中間件
局部中間件只對特定的路由或路由組生效。
authorized := func() gin.HandlerFunc {return func(c *gin.Context) {// 中間件邏輯c.Next()}
}r.GET("/protected", authorized(), func(c *gin.Context) {c.String(200, "Protected resource")
})
這里 authorized()
中間件只對 /protected
路由生效。
全局中間件
全局中間件對所有路由都生效。
logger := func() gin.HandlerFunc {return func(c *gin.Context) {// 中間件邏輯c.Next()}
}r.Use(logger())
通過 r.Use()
方法添加全局中間件,它會在每個請求處理前執行,可用于日志記錄、請求驗證等通用功能。