一、Gin 简介
- Gin 是使用 Go/Golang 语言实现的 HTTP Web 框架。接口简洁,性能极高。截止 1.4.0 版本,包含测试代码,仅 14K,其中测试代码 9K 左右,也就是说框架源码仅 5K 左右
- Gin 特性:
- 快速:路由不使用反射,基于 Radix 树,内存占用少
- 中间件:HTTP 请求,可先经过一系列中间件处理,例如:Logger,Authorization,GZIP 等。这个特性和 NodeJs 的
Koa
框架很像。中间件机制也极大地提高了框架的可扩展性 - 异常处理:服务始终可用,不会宕机。Gin 可以捕获 panic,并恢复。而且有极为便利的机制处理 HTTP 请求过程中发生的错误
- JSON:Gin 可以解析并验证请求的 JSON。这个特性对 Restful API 的开发尤其有用
- 路由分组:例如将需要授权和不需要授权的 API 分组,不同版本的 API 分组。而且分组可嵌套,且性能不受影响
- 渲染内置:原生支持 JSON,XML 和 HTML 的渲染
二、Hello World
1 | package main |
- 首先,使用
gin.Default()
生成了一个实例,这个实例即 WSGI 应用程序 - 接下来,使用
r.Get("/", ...)
声明了一个路由,告诉 Gin 什么样的 URL 能触发传入的函数,这个函数返回想要显示在用户浏览器中的信息 - 最后用
r.Run()
函数来让应用运行在本地服务器上,默认监听端口是 8080,可以传入参数设置端口,如r.Run(":9999")
1 | $ curl localhost:8080 |
三、路由
- 路由方法有
GET
、POST
、PUT
、PATCH
、DELETE
、OPTIONS
等
1. 无参数
1 | r.GET("/", func(c *gin.Context) { |
2. 解析路径参数
- 动态的路由,如
/user/:name
,可以通过调用不同的 url 来传入不同的 name。/user/:name/*role
,*
代表可选
1 | r.GET("/user/:name", func(c *gin.Context) { |
3. 获取 Query 参数
- 匹配
users?name=xxx&role=xxx
,role 可选
1 | r.GET("/users", func(c *gin.Context) { |
4. 获取 POST 参数
1 | r.POST("/form", func(c *gin.Context) { |
5. Query 和 POST 混合参数
1 | r.POST("/posts", func(c *gin.Context) { |
6. Map 参数
1 | r.POST("/post", func(c *gin.Context) { |
7. 重定向
1 | r.GET("/redirect", func(c *gin.Context) { |
8. 分组路由
- 利用分组路由可以更好地实现权限控制,例如将需要登录鉴权的路由放到同一分组中去,简化权限控制
1 | defaultHandler := func(c *gin.Context) { |
四、上传文件
1. 单个文件
1 | r.POST("/upload1", func(c *gin.Context) { |
2. 多个文件
1 | r.POST("/upload2", func(c *gin.Context) { |
五、HTML 模板
1 | type student struct { |
- Gin 默认使用 Go 语言标准库的模板
text/template
和html/template
,语法与标准库一致,支持各种复杂场景的渲染 - 参考官方文档 text/template,html/template
六、中间件
1 | // 作用于全局 |
- 自定义中间件:
1 | func Logger() gin.HandlerFunc { |
七、热加载调试
- Python 的
Flask
框架,有 debug 模式,启动时传入 debug=True 就可以热加载了。即更改源码,保存后,自动触发更新,浏览器上刷新即可。免去了杀进程、重新启动之苦 - Gin 原生不支持,但有很多额外的库可以支持。例如 fresh
1 | $ go get github.com/pilu/fresh |