3.2 KiB
3.2 KiB
第 3 章 Gin 入门
学完本章你将:理解 Gin 的定位与优势、跑通第一个 Gin 服务、看懂 Gin 与标准库 net/http 的关系。
3.1 为什么选 Gin
- 快:基于 httprouter 的前缀树路由,性能居 Go Web 框架前列
- 简洁:
gin.Default()一行起服务,c.JSON一行返回 - 生态:中间件、绑定、验证、分组等开箱即用
- 本项目已选型:
go.mod中github.com/gin-gonic/gin v1.12.0
对比:
| 方案 | 特点 | 适合 |
|---|---|---|
net/http |
标准库,无依赖,可控 | 小服务、学习 |
| Gin | 高性能、API 友好 | RESTful API、中大型项目 |
| Echo/Fiber | 类似 Gin,Fiber 基于 fasthttp | 追求极致性能或特定风格 |
3.2 安装与初始化
本项目已初始化,可直接 make tidy。从零新建:
mkdir myapp && cd myapp
go mod init myapp
go get github.com/gin-gonic/gin
3.3 Hello World
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default() // 含 Logger + Recovery 中间件
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "pong"})
})
r.Run(":8080") // 监听 0.0.0.0:8080
}
运行 go run main.go,访问 http://localhost:8080/ping。
gin.H是map[string]any的别名,方便构造 JSONc.JSON(code, obj)自动设置Content-Type: application/json
3.4 Gin 与 net/http 的关系
Gin 不是另起炉灶,而是对 net/http 的封装:
// Gin 实现了 http.Handler 接口,所以可直接给 http.Server
srv := &http.Server{
Addr: ":8080",
Handler: r, // r 是 *gin.Engine,实现了 ServeHTTP
}
srv.ListenAndServe()
本项目 cmd/server/main.go 正是这种写法,以便支持优雅关闭(srv.Shutdown)。若用 r.Run() 则无法优雅关闭,仅适合 demo。
gin.Context 包装了 http.Request 与 http.ResponseWriter,提供 Param/Query/Bind/JSON 等快捷方法。
3.5 gin.Default() vs gin.New()
// Default 自带 Logger + Recovery
r := gin.Default()
// New 空引擎,需手动注册(本项目采用,便于替换为 Zap)
r := gin.New()
r.Use(middleware.Recovery())
r.Use(middleware.ZapLogger())
本项目 internal/router/router.go 使用 gin.New() 并注册自定义 Zap 日志与 Recovery,生产更可控。
3.6 运行模式
gin.SetMode(gin.DebugMode) // 开发:详细日志
gin.SetMode(gin.ReleaseMode) // 生产:精简日志
gin.SetMode(gin.TestMode) // 测试
本项目由 config.yaml 的 server.mode 控制,在 router.New 中 gin.SetMode(cfg.Server.Mode)。
3.7 项目初始化对照
本项目入口 cmd/server/main.go 关键步骤:
config.Load()加载配置logger.Init初始化 Zaprouter.New(cfg)创建 Gin 引擎http.Server+ goroutine 启动signal.Notify等待退出信号,srv.Shutdown优雅关闭
这是生产级 Gin 服务的标准启动模板,建议熟记。
3.8 动手练习
- 用
gin.Default()写一个返回当前时间的/time接口。 - 改为
gin.New()+ 自定义 Logger,观察差异。 - 将启动方式从
r.Run改为http.Server+ 优雅关闭。