gin是一款輕量級的go web開發框架,官方文件
https://gin-gonic.com/docs/examples/
1.gin web專案結構
參考
https://github.com/voyagegroup/gin-boilerplate
gin+protobuf wire參考
https://github.com/mohuishou/blog-code/tree/main/01-go-training/04-project/10-layout
2.gin web quick start
https://gin-gonic.com/docs/quickstart/
在官方文件中提供了2個quick start的demo,一個稍微複雜,一個比較簡單
簡單的例子如下,建立一個/ping介面,返回pong
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() // listen and serve on 0.0.0.0:8080 }
3.路由分組
如果gin專案的介面比較多的話,可以使用路由分組
https://gin-gonic.com/docs/examples/grouping-routes/
參考:【Go】基於 Gin 從0到1搭建 Web 管理後臺系統後端服務(三)路由、自定義校驗器和 Redis
4.資料繫結
將請求的引數傳遞給介面中的變數,需要使用gin的資料繫結
如果是path parameter
使用c.Param("name")
https://gin-gonic.com/docs/examples/param-in-path/
使用c.ShouldBindUri(&person)
https://gin-gonic.com/docs/examples/bind-uri/
如果是query parameter或者post請求的form-data
使用c.ShouldBind(&user)
https://gin-gonic.com/docs/examples/bind-query-or-post/
5.統一的response
可以如下定義統一的介面response,其中的interface{}類似java中的泛型T
type ControllerResponse struct { Code int Msg string Data interface{} } func Response(ctx *gin.Context, code int, msg string, data interface{}) { resp := ControllerResponse{Code: code, Msg: msg, Data: data} ctx.JSON(code, resp) ctx.Abort() } func Success(ctx *gin.Context, msg string, data interface{}) { Response(ctx, 200, msg, data) } func Fail(ctx *gin.Context, msg string, data interface{}) { Response(ctx, 500, msg, data) }
參考:go語言web開發系列之十五:gin框架統一定義API錯誤碼
6.middleware中介軟體
1.使用middleware
下面定義了3個middleware
// MiddleWare1 定義中介軟體1 func MiddleWare1() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("前 m1") c.Next() fmt.Println("後 m1") } } // MiddleWare2 定義中介軟體2 func MiddleWare2() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("前 m2") c.Next() fmt.Println("後 m2") } } // MiddleWare3 定義中介軟體3 func MiddleWare3() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("前 m3") c.Next() fmt.Println("後 m3") } }
在gin中新增middleware
func main() { // 建立路由 engine := gin.Default() // 註冊中介軟體 engine.Use(MiddleWare1(), MiddleWare2(), MiddleWare3()) // 路由規則 engine.GET("/ping", func(c *gin.Context) { fmt.Println("hello world") c.JSON(200, gin.H{"msg": "pong"}) }) err:=engine.Run(":3000") if err != nil { fmt.Println(err) } }
輸出如下
前 m1 前 m2 前 m3 hello world 後 m3 後 m2 後 m1 [GIN] 2023/12/25 - 00:06:11 | 200 | 35.726µs | 127.0.0.1 | GET "/ping"
介面返回pong
2.Next()和Abort()
Next()之前的程式碼會在執行HandlerFunc之前執行,之後的程式碼會在執行HandlerFunc之後執行
如果將middleware2中的c.Next()修改成c.Abort()
// MiddleWare2 定義中介軟體2 func MiddleWare2() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("前 m2") c.Abort() fmt.Println("後 m2") } }
則輸出將會如下
前 m1 前 m2 後 m2 後 m1 [GIN] 2023/12/25 - 00:11:05 | 200 | 16.262µs | 127.0.0.1 | GET "/ping"
介面無返回
可以Abort()不會阻止當前middleware的執行,但是會中止下游middleware以及HandlerFunc的執行
參考:[Go Package] gin 中介軟體流程控制:c.Next() / c.Abort()