Gin 路由
路由
核心功能
- 路由系统可根据请求方法、请求路径和路径参数来识别转发
- 可设置一个或者多个中间件用于在请求处理器前后处理特殊的事件
- 可以分组设置,将一个或多个中间件作用在一组多个路由上
基本语法
//构建路由对象并注册请求路径对应的处理器
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "ping",
})
})
// 监听并在 0.0.0.0:8080 上启动服务
r.Run()
可以将路由的定义放在单独的文件中完成,如 /router/api.go
:
// file: /router/api.go
func APIRouter() *gin.Engine {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "ping"
})
})
// 更多的注册
// r.POST()
// r.DELETE()
// r.PUT()
return r
}
然后,在 main()
中完成调用和初始化,并启动监听:
// file /main.go
func main() {
// 初始化路由
r := router.APIRouter()
// 启动服务
r.Run()
}
请求方法
快捷方法
除 GET
方法外,路由系统还支持任意方式的请求:DELETE
、GET
、HEAD
、OPTIONS
、PATCH
、POST
、PUT
。
通用方法
如果需要接收其他的请求方式,可以使用通用的方法 Handle
来注册:
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes
其中 httpMethod
就是请求方法字符串,例如 TRACE
、CONNECT
等。
任意方法
若需要监听同一个请求路径的多个任意方法,可以使用 Any()
:
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes
处理器
handler 处理器(也被成为控制器),用来处理 HTTP 请求:
type HandlerFunc func(*Context)
handler 就是一个可以接收 *Context
类型的 (*gin.Context)
参数的函数。
处理器可以分为两类,中间件和请求处理器(也叫业务逻辑处理器)。在 router.GET()
之类的方法中,最后一个 Handler 就是请求处理器,除此之外前边的都是中间件。
处理器被调用时,会接收一个 *Context
参数,是请求上下文,用于获取请求和响应操作。
路由参数
路由参数指在请求路径中定义的参数,例如请求的 URI 是 /user/21
,21 作为用户的 ID,那么 21 就是路由参数。路由参数与查询字符串有区别,例如 /user?ID=21
,这个 ID=21
叫做查询字符串。
使用路由参数的好处是将动态 URL 变为静态 URL,因为请求客户端会认为路由参数不是变化的数据,因此被视为静态 URL.
如需定义带有路由参数的路径,需要使用 :param
或 *param
的语法在路径中。
必选参数
使用 :param
的语法完成必选参数的定义,例如 /user/:ID
,即可匹配 /user/21
这个 URI,但不能匹配 /user
或 /user/
。例如
router.GET("/user/:ID", func(c *gin.Context) {
ID := c.Para("ID")
})
可选参数
使用 *param
的语法完成可选参数的定义,例如 /user/*ID
可以匹配 /user/21
和 /user
或 /user/
的 URI。例如:
router.GET("/user/*ID", func(c *gin.Context) {
ID := c.Para("ID")
})
若没有匹配到,则 ID 为空字符串。
获取参数
使用 gin.Context 对象的 c.Param("param")
来获取参数值。
路由分组
路由分组用于将多个路由进行统一的处理,例如统一的前缀,统一的中间件等。例如在需要做认证的业务逻辑时,就可以将大量的需要身份认证的路由定义在一个组中,集中设置用于认证校验的中间件。
创建分组
使用函数 router.Group()
完成分组的创建。创建时可以提供路径前缀和公用中间件:
func (group *RouterGroup) Group(relativePath string, handlers ...handlerFunc) *RouterGroup
调用该函数后,会形成一个分组路由对象,组内的路由需要使用该对象完成处理器的注册,例如:
// 简单的路由组
v1 := router.Group("/v1")
{
v1.Post("/login", loginEndpoint)
v1.Post("/submit", submitEndpoint)
v1.Post("/delete", deleteEndpoint)
}
v2 := router.Group("/v2")
{
v2.Post("/login", loginEndpoint)
v2.Post("/submit", submitEndpoint)
v2.Post("/delete", deleteEndpoint)
}
上面的代码创建了两个路由分组,前缀分别是 v1 和 v2。
中间件
中间件 middleware,也是一种处理器。主要用于在多个业务逻辑中间重用代码,例如认证校验、日志处理等。中间件需要附加在路由上,使用 router.User()
方法。
我们在使用 gin.Default()
初始化路由对象时,会随之附加两个中间件 Logger
和 Recovery
,用于完成日志和恢复的相关处理:
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
// 注册中间件
engine.Use(Logger(), Recovery())
return engine
}
若不想使用任何中间件,可以使用函数 gin.New()
来创建空白的路由,例如:
router := gin.New()
此时的路由对象,不会自动附加任何的中间件。
启动监听
函数 router.Run()
用于启动 HTTP 监听,函数接收监听地址作为参数,默认地址为 :8080
。