整体结构
基本示例
从最简单的示例 basic 开始。
basic
main
func main() {r := setupRouter()// Listen and Server in 0.0.0.0:8080r.Run(":8080")}
这部分代码简单、直接,创建好路由后,直接在端口 8080 开启服务。
setupRouter
创建 gin.Engine 结构,gin.Engine 满足 gin.IRouter 接口
r := gin.Default()
添加 /ping 路由,普通路由,没有参数
r.GET("/ping", func(c *gin.Context) {c.String(http.StatusOK, "pong")})
添加带参数路由
r.GET("/user/:name", func(c *gin.Context) {user := c.Params.ByName("name")value, ok := db[user]if ok {c.JSON(http.StatusOK, gin.H{"user": user, "value": value})} else {c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})}})
添加路由组
authorized := r.Group("/", gin.BasicAuth(gin.Accounts{"foo": "bar", // user:foo password:bar"manu": "123", // user:manu password:123}))authorized.POST("admin", func(c *gin.Context) {user := c.MustGet(gin.AuthUserKey).(string)// Parse JSONvar json struct {Value string `json:"value" binding:"required"`}if c.Bind(&json) == nil {db[user] = json.Valuec.JSON(http.StatusOK, gin.H{"status": "ok"})}})
从基本示例中,可以看到 gin 的一些基本特性
- 支持路由分组
- 支持参数验证
从以上基础,即可展开分析。
源码分析
全局概览
从上图,结合代码,可以知道 gin 框架的基本关系。gin.Engine 实现 http.Handler 接口,做为 http.Server 的参数接入 http 模块儿。内部的 IRouter 接口,负责路由管理,IRouter 的 Group 方法会生成一个新结构体 RouterGroup,RouterGroup 实现 IRouter 与 IRoutes 接口, RouterGroup 可通过 engine 属性,找到其挂载的 Engine 结构。
再看一下 Engine 结构定义
type Engine struct {RouterGroup// ...}
RouterGroup 结构实现了 IRoutes 接口来管理路由。Engine 匿名包含 RouterGroup 结构,也自然的实现了 IRouter 与 IRoutes 接口。
Group 方法
因为匿名包含,Engine 的 Group 方法会直接使用 RouterGroup 的 Group 方法。执行过程如下图所示:
