1 概念
What is Gin?
Gin is a web framework written in Golang.
It features a martini-like API with much better performance, up to 40 times faster.
If you need performance and good productivity, you will love Gin.
翻译:
Gin是一个用Golang写的网络框架。
它有一个马提尼式的API,性能更好,速度快40倍。
如果您需要性能和良好的生产力,您会喜欢Gin。
特点:
- 快速:基于基树路由,内存占用小。没有反射。可预测的API的性能。
- 中间件支持:传入的HTTP请求可以由中间件链和最终操作处理。例如:Logger, Authorization, GZIP,最后在DB中发布消息。
- 轻松捕获故障:Gin可以捕捉到HTTP请求期间发生的恐慌并恢复它。 这样,您的服务器将始终可用。 也可以将这种恐慌报告给哨兵!
- JSON验证:Gin可以解析和验证请求的JSON,例如检查需要的值是否存在。
- 路线分组:更好地组织你的路线。 授权需要和不需要,不同的API版本。 此外,组可以无限制地嵌套而不会降低性能。
- 错误管理:Gin提供了一种方便的方法来收集HTTP请求期间发生的所有错误。最终,中间件可以将它们写入日志文件、数据库并通过网络发送。
- 内置渲染:Gin为JSON、XML和HTML渲染提供了一个易于使用的API。
- 可扩展的:创建新的中间件非常简单,只需查看示例代码即可。
2 安装
go get -u github.com/gin-gonic/gin
3 初步使用
3.1 HelloWorld
package main import "github.com/gin-gonic/gin" func main() { r := gin.Default() r.GET("/Hello", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "HelloWorld", }) }) r.Run("127.0.0.1:8899") // 监听并在 0.0.0.0:8899 上启动服务 }
测试:
curl http://127.0.0.1:8899/hello {"message": "HelloWorld"}
3.2 获取请求参数
(1)http://127.0.0.1:8899?name=zs型参数
r.GET("/name", func(c *gin.Context) { query := c.Query("name") //等价于:c.Request.URL.Query().Get("name") c.JSON(200, "Hello "+query) })
测试:
curl http://127.0.0.1:8899/name?name=zs "Hello zs"
(2)http://127.0.0.1:8899/name/{zs}型参数
r.GET("/name/:name", func(c *gin.Context) { name := c.Param("name") c.JSON(200, "Hello "+name) })
测试:
curl http://127.0.0.1:8899/name/zs "Hello zs"
3.3 获取请求体
(1)一般获取请求体
结构体:
type Student struct { Name string `json:"name"` Age int `json:"age"` }
方法:
r.POST("/stu", func(c *gin.Context) { body := c.Request.Body bytes, err := ioutil.ReadAll(body) stu := Student{} json.Unmarshal(bytes, &stu) if err != nil { panic(err) } c.JSON(200, stu) })
测试:
(2)获取请求体与结构体绑定
r.POST("/stu", func(c *gin.Context) { stu := Student{} // c.ShouldBindJSON 使用了 c.Request.Body,不可重用。 c.ShouldBindJSON(&stu) c.JSON(200, stu) })
测试:
3.4 路由组
路由组就好比一层配置,增加了一个层级,以便于区分不同分组的URL,例如下面的代码中,如果要请求FindAppInfoById方法,路径就是/appInfo/save,完整路径就是http://127.0.0.1:8899/appInfo/save
func main() { r := gin.Default() //路由组 appInfoGroup := r.Group("/appInfo") { appInfoGroup.POST("/save", controller.SaveAppInfo) appInfoGroup.GET("/find/:id", controller.FindAppInfoById) appInfoGroup.GET("/findAll", controller.FindAllAppInfo) } r.Run("127.0.0.1:" + utils.IntToString(port)) } // FindAppInfoById 自定义HTTP方法 func FindAppInfoById(c *gin.Context) { id := c.Param("id") ...... c.JSON(200, id) } func SaveAppInfo(c *gin.Context) { ...... } func FindAllAppInfo(c *gin.Context) { ...... }
4 Gin实现拦截器
func main() { r := gin.Default() //增加拦截器 r.Use(interceptor.HttpInterceptor()) ...... r.Run("127.0.0.1:" + utils.IntToString(port)) }
拦截器实现:
// HttpInterceptor 自定义中间件 func HttpInterceptor() gin.HandlerFunc { return func(c *gin.Context) { t := time.Now() // 设置 example 变量 c.Set("example", "12345") // 请求前 log.Print("--------------拦截器-------------") //定义错误,终止并返回该JSON //c.AbortWithStatusJSON(500, "error") requestURI := c.Request.RequestURI fmt.Println(requestURI) //通过请求 c.Next() // 请求后 latency := time.Since(t) log.Print(latency) // 获取发送的 status status := c.Writer.Status() log.Println(status) } }
~