Gin 是一个用 Golang 编写的 Web 框架。
快速开始
需要使用 Go 1.16 及以上版本
- 下载
go get -u github.com/gin-gonic/gin |
- 引入工程
import "github.com/gin-gonic/gin" |
你可能需要使用go mod进行依赖管理
- 写入一段简单的代码(main.go)
package main |
- 运行
go run main.go |
使用浏览器访问http://127.0.0.1:8080/ping可以收到来自服务器的响应
特性
Gin v1 稳定的特性:
- 零分配路由。
- 仍然是最快的 http 路由器和框架。
- 完整的单元测试支持。
- 实战考验。
- API 冻结,新版本的发布不会破坏你的代码。
Jsoniter
Gin 使用 encoding/json 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 jsoniter。
go build -tags=jsoniter . |
测试
HTTP 测试首选 net/http/httptest 包。
测试用例示例:
package main |
package main |
功能支持
参数相关
模型绑定和验证
要将请求体绑定到结构体中,使用模型绑定。 Gin 目前支持 JSON、XML、YAML 和标准表单值的绑定(foo=bar&boo=baz)。
Gin 使用 go-playground/validator/v10 进行验证。 查看标签用法的全部文档.
使用时,需要在要绑定的所有字段上,设置相应的 tag。
Gin 提供了两类绑定方法:
- Type - Must bind
Methods - Bind, BindJSON, BindXML, BindQuery, BindYAML
Behavior - 这些方法属于 MustBindWith 的具体调用。 如果发生绑定错误,则请求终止,并触发 c.AbortWithError(400, err).SetType(ErrorTypeBind)。响应状态码被设置为 400 并且 Content-Type 被设置为 text/plain; charset=utf-8。 如果您在此之后尝试设置响应状态码,Gin 会输出日志 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422。 如果您希望更好地控制绑定,考虑使用 ShouldBind 等效方法。 - Type - Should bind
Methods - ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery, ShouldBindYAML
Behavior - 这些方法属于 ShouldBindWith 的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。
使用 Bind 方法时,Gin 会尝试根据 Content-Type 推断如何绑定。 如果你明确知道要绑定什么,可以使用 MustBindWith 或 ShouldBindWith。
你也可以指定必须绑定的字段。 如果一个字段的 tag 加上了 binding:”required”,但绑定时是空值, Gin 会报错。
// 绑定 JSON |
查询字符串参数
func main() { |
路由参数
func main() { |
Cookie
读取和写入
cookie, err := c.Cookie("gin_cookie") |
自定义验证器
var bookableDate validator.Func = func(fl validator.FieldLevel) bool { |
日志相关
日志记录
// 记录到文件。 |
控制日志输出颜色
// 禁止日志的颜色 |
定义路由日志的格式
gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) { |
自定义日志文件
router := gin.New() |
路由相关
路由组
router := gin.Default() |
使用 HTTP 方法
router := gin.Default() |
在中间件中使用 Goroutine
当在中间件或 handler 中启动新的 Goroutine 时,不能使用原始的上下文,必须使用只读副本。
r.GET("/long_async", func(c *gin.Context) { |
重定向
HTTP 重定向很容易。 内部、外部重定向均支持。
r.GET("/test", func(c *gin.Context) { |
通过 POST 方法进行 HTTP 重定向。请参考 issue:#444
r.POST("/test", func(c *gin.Context) { |
路由(内部)重定向,使用 HandleContext:
r.GET("/test", func(c *gin.Context) { |
使用 BasicAuth 中间件
// 模拟一些私人数据 |
自定义中间件
func Logger() gin.HandlerFunc { |
静态文件相关
静态文件服务
func main() { |
静态资源嵌入
你可以使用 go-assets 将静态资源打包到可执行文件中。
func main() { |
请参阅 assets-in-binary/example01 目录中的完整示例。
html 渲染
使用 LoadHTMLGlob() 或者 LoadHTMLFiles() 加载模板
func main() { |
templates/index.tmpl
<html> |
自定义分隔符
r := gin.Default() |
自定义模板方法
合作开发时可能会使不错的工具。
|
自定义模板渲染器
根据需求生成渲染树, 包括可以随意修改分隔符等信息。可以用来做静态资源打包。
import "html/template" |
数据返回
PureJSON
通常,JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c。如果要按字面对这些字符进行编码,则可以使用 PureJSON。
func main() { |
SecureJSON
使用 SecureJSON 防止 json 劫持。如果给定的结构是数组值,则默认预置 “while(1),” 到响应体。会不会有被误伤的。
func main() { |
AsciiJSON
使用 AsciiJSON 生成具有转义的非 ASCII 字符的 ASCII-only JSON。
func main() { |
XML/JSON/YAML/ProtoBuf 渲染
func main() { |
JSONP
使用 JSONP 向不同域的服务器请求数据。如果查询参数存在回调,则将回调添加到响应体中。
JSONP 是一种跨域请求数据的方式,利用
<script>动态的生成 js 回调函数,在浏览器执行从而实现数据跨域传输。
func main() { |
安全页眉
使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。
func main() { |
其他
从 reader 读取数据
func main() { |
HTTP2 server 推送
主动在浏览器请求页面时候浏览器发送相关资源,如 js css 文件,提高效率。
http.Pusher 仅支持 go1.8+
var html = template.Must(template.New("https").Parse(` |
自定义 HTTP 配置
直接使用 http.ListenAndServe(),修改端口如下所示:
router := gin.Default() |
或者配置 Server
s := &http.Server{ |
支持 Let’s Encrypt
一行代码支持 LetsEncrypt HTTPS servers 示例。
func main() { |
上传文件
单文件
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB) |
多文件
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB) |
运行多个服务
var ( |
优雅地重启或停止
我们可以使用 fvbock/endless 来替换默认的 ListenAndServe。
router := gin.Default() |
替代方案:
- manners:可以优雅关机的 Go Http 服务器。
- graceful:Graceful 是一个 Go 扩展包,可以优雅地关闭 http.Handler 服务器。
- grace:Go 服务器平滑重启和零停机时间部署。
参考
- 本文作者: Tiny Beer
- 本文链接: https://tinybeer.github.io/2024/05/24/Gin学习笔记/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!
