Gin 框架
1月 13
Go
Go
字数统计: 1.9k(字)
阅读时长: 9(分)
概述 本文摘取网上文章汇总。Gin 是一个 golang 的微框架,封装比较优雅,相对于 echo,Gin 更适用于企业开发。
一 Gin 安装 1 go get -v -u github.com/gin-gonic/gin
二 路由使用 1. 默认中间件使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport "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() }
2. 无中间件的路由 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package mainimport ( "os" "github.com/gin-gonic/gin" "github.com/gogap/logrus" ) func init () { logrus.SetOutput(os.Stdout) logrus.SetLevel(logrus.DebugLevel) logrus.Debug("logrus init" ) } func middleware1 (params string ) gin.HandlerFunc { return func (c *gin.Context) { logrus.Debugf("middleware1:%s" , params) c.Next() } } func middleware2 (params string ) gin.HandlerFunc { return func (c *gin.Context) { logrus.Debugf("middleware1:%s" , params) c.Next() } } func pingEndPoint (c *gin.Context) { c.JSON(200 , gin.H{ "message" : "pong" , }) } func main () { r := gin.New() r.Use(gin.Logger()) r.Use(gin.Recovery()) r.Use(middleware1("comm" )) r.GET("/ping" , middleware2("ping" ), pingEndPoint) r.GET("/ping1" , pingEndPoint) r.Run(":8080" ) }
3. 动态路由 有时候我们需要动态的路由,如 /user/:id
,通过调用的 url 来传入不同的 id .在 Gin 中很容易处理这种路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package mainimport ( "net/http" "github.com/gin-gonic/gin" ) func main () { router := gin.Default() router.GET("/user/:name" , func (c *gin.Context) { name := c.Param("name" ) c.String(http.StatusOK, "Hello %s" , name) }) 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) }) router.Run(":8080" ) }
4. 路由组 一些情况下,我们会有统一前缀的 url 的需求,典型的如 Api 接口版本号 /v1/something
。Gin 可以使用 Group 方法统一归类到路由组中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package mainimport ( "github.com/gin-gonic/gin" ) func newEndPoint (name string ) gin.HandlerFunc { return func (c *gin.Context) { c.String(200 , "request[%s] ok!" , name) } } func main () { loginEndpoint := newEndPoint("login" ) submitEndpoint := newEndPoint("submit" ) readEndpoint := newEndPoint("read" ) router := gin.Default() v1 := router.Group("/v1" ) { v1.GET("/login" , loginEndpoint) v1.GET("/submit" , submitEndpoint) v1.GET("/read" , readEndpoint) } v2 := router.Group("/v2" ) v2.GET("/login" , loginEndpoint) v2.GET("/submit" , submitEndpoint) v2.GET("/read" , readEndpoint) router.Run(":8080" ) }
三 查询参数 1. URL 查询参数 假定一个 url 为 /welcome?firstname=Jane&lastname=Doe
,我们想获取参数 firstname
的内容,可以使用c.Query
方法。该方法始终返回一个 string
类型的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( "net/http" "github.com/gin-gonic/gin" ) func main () { router := gin.Default() router.GET("/welcome" , func (c *gin.Context) { firstname := c.DefaultQuery("firstname" , "Guest" ) lastname := c.Query("lastname" ) c.String(http.StatusOK, "Hello %s %s" , firstname, lastname) }) router.Run(":8080" ) }
2. 其他格式的数据 一些复杂的场景下,如用户直接 POST一段 json字符串到应用中,我们需要获取原始数据,这时需要用 c.GetRawData来获取原始字节。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package mainimport ( "os" "github.com/gin-gonic/gin" "github.com/gogap/logrus" ) func init () { logrus.SetOutput(os.Stdout) logrus.SetLevel(logrus.DebugLevel) logrus.Debug("logrus init" ) } func main () { router := gin.Default() router.POST("/post" , func (c *gin.Context) { d, err := c.GetRawData() if err != nil { logrus.Fatalln(err) } logrus.Println(string (d)) c.String(200 , "ok" ) }) router.Run(":8080" ) }
测试:
1 curl -v -X POST http://localhost:8080/post -H 'content-type: application/json' -d '{ "name": "joy","address":"beijing" }'
四 数据绑定 Gin 提供了非常方便的数据绑定功能,可以将用户传来的参数自动跟我们定义的结构体绑定在一起。
1. 只绑定 URL 查询参数 使用 c.ShouldBindQuery
方法,可以自动绑定 Url 查询参数到 struct
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package mainimport ( "os" "github.com/Sirupsen/logrus" "github.com/gin-gonic/gin" ) type Person struct { Name string `form:"name"` Address string `form:"address"` } func init () { logrus.SetOutput(os.Stdout) logrus.SetLevel(logrus.DebugLevel) logrus.Debug("logrus init" ) } func main () { route := gin.Default() route.Any("/bind" , startPage) route.Run(":8080" ) } func startPage (c *gin.Context) { var person Person if c.ShouldBindQuery(&person) == nil { logrus.Info("====== Only Bind By Query String ======" ) logrus.Info(person.Name) logrus.Info(person.Address) } c.String(200 , "Success" ) }
测试
1 curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing"
2. 绑定 URL 查询参数和 POST 参数 使用 c.ShouldBind
方法,可以将参数自动绑定到 struct
.该方法是会检查 Url 查询字符串和 POST 的数据,而且会根据 content-type
类型,优先匹配JSON
或者 XML
,之后才是 Form
. 有关详情查阅 这里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package mainimport ( "log" "time" "github.com/Sirupsen/logrus" "github.com/gin-gonic/gin" ) type Person struct { Name string `form:"name"` Address string `form:"address"` Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"` } func main () { route := gin.Default() route.Any("/bind" , startPage, lastMiddleware) route.Run(":8080" ) } func lastMiddleware (c *gin.Context) { logrus.Info("last middleware" ) } func startPage (c *gin.Context) { var person Person if c.ShouldBind(&person) == nil { log.Println(person.Name) log.Println(person.Address) log.Println(person.Birthday) } c.String(200 , "Success" ) c.Next() }
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 此时获取 body 中内容进行绑定 curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing" -H 'content-type: application/json' -d '{ "name": "joy1","address":"beijing1" }' # 获取 url 参数内容进行绑定 curl -v -X GET "http://localhost:8080/bind?name=joy&address=beijing" # 能获取到 url 参数内容并进行绑定 curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing" # 能获取到 url 参数内容并进行绑定 curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing" -d '' # 无法获取到 url 参数自动进行绑定 curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing" -H 'content-type: application/json' curl -v -X POST "http://localhost:8080/bind?name=joy&address=beijing" -H 'content-type: application/json' -d ''
五 生产环境运行 变量更改 Gin 运行模式为发布模式
设置环境变量: export GIN_MODE=release 在代码中设置: gin.SetMode(gin.ReleaseMode)
链接