gin路由源码
// POST is a shortcut for router.Handle("POST", path, handle).
func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("POST", relativePath, handlers)
}
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("GET", relativePath, handlers)
}
// DELETE is a shortcut for router.Handle("DELETE", path, handle).
func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("DELETE", relativePath, handlers)
}
// PATCH is a shortcut for router.Handle("PATCH", path, handle).
func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("PATCH", relativePath, handlers)
}
// PUT is a shortcut for router.Handle("PUT", path, handle).
func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("PUT", relativePath, handlers)
}
// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle).
func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("OPTIONS", relativePath, handlers)
}
// HEAD is a shortcut for router.Handle("HEAD", path, handle).
func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("HEAD", relativePath, handlers)
}
// Any registers a route that matches all the HTTP methods.
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
group.handle("GET", relativePath, handlers)
group.handle("POST", relativePath, handlers)
group.handle("PUT", relativePath, handlers)
group.handle("PATCH", relativePath, handlers)
group.handle("HEAD", relativePath, handlers)
group.handle("OPTIONS", relativePath, handlers)
group.handle("DELETE", relativePath, handlers)
group.handle("CONNECT", relativePath, handlers)
group.handle("TRACE", relativePath, handlers)
return group.returnObj()
}
gin支持 POST、GET、DELETE、PATCH、PUT、OPTIONS、HEAD、Any方法
常用的restful api的方法都支持,可以放心大胆的做reful api开发。最后的Any方法可以就收任何请求。
添加路由
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
第一行代码,创建了一个gin的实例对象,
然后用这个gin实例对象 r.GET()就可以注册一个GET请求。
其他类型的请求也只需要再写r.POST(),r.DELETE()…就行。
这些方法接受2个参数,
一个是路由对应的路径,👆🌰中,就是”/ping”,访问127.0.0.1:8080/ping即可访问到次路由。
第二个参数是一个处理函数,用来处理路由的请求。
此处理函数一定要接受gin.Context的指针 c,就是一个gin的上下文。
来看下gin.Context的源码
//上下文是gin的重要概览。它允许我们在中间件之间传递变量,
//例如,管理流、验证请求的JSON并呈现JSON响应。
type Context struct {
writermem responseWriter
Request *http.Request
Writer ResponseWriter
Params Params
handlers HandlersChain
index int8
engine *Engine
// Keys is a key/value pair exclusively for the context of each request.
Keys map[string]interface{}
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string
}
gin.Context是一个结构体,它包含很多东西,例如gin的实例:engine Engine,请求内容:Request http.Request,请求参数:Params Params等等。
不仅如此,gin.Context还有很多方法,常用的有:
// 用于获取路径参数
func (c *Context) Param(key string) string {
return c.Params.ByName(key)
}
// 用于获取query参数 GET /path?id=1234&name=Manu&value=
func (c *Context) Query(key string) string {
value, _ := c.GetQuery(key)
return value
}
//请求头
func (c *Context) Header(key, value string) {
if value == "" {
c.Writer.Header().Del(key)
return
}
c.Writer.Header().Set(key, value)
}
// cookie
func (c *Context) Cookie(name string) (string, error) {
cookie, err := c.Request.Cookie(name)
if err != nil {
return "", err
}
val, _ := url.QueryUnescape(cookie.Value)
return val, nil
}
// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
c.Render(code, render.JSON{Data: obj})
}
基本上,常用的处理请求的方法都挂载到context上,这样方便我们进行数据传递和处理请求。
路由分组
使用g实例的Group来进行分组
g:=gin.New()
u:=g.Group("/v1")
{
u.POST("/user", user.Create) // 创建用户
u.DELETE("/user/:id", user.Delete) // 删除用户
u.PUT("/user/:id", user.Update) // 更新用户
u.GET("/user", user.List) // 用户列表
u.GET("/user/:username", user.Get) // 获取指定用户的详细信息
}
这样,大括号内的路由前面都添加了一个/v1的路由,方便我们对路由进行分组和版本控制
看一下g.Group()的源码:
// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
// For example, all the routes that use a common middleware for authorization could be grouped.
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
return &RouterGroup{
Handlers: group.combineHandlers(handlers),
basePath: group.calculateAbsolutePath(relativePath),
engine: group.engine,
}
}
g.Group()返回一个新的gin路由群*RouterGroup,将原来的gin实例engine克隆一遍,将路径和处理函数合并一下。