1 概念
官网: https://gin-gonic.com/zh-cn/
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)
}
}
~