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 responseWriterRequest *http.RequestWriter ResponseWriterParams Paramshandlers HandlersChainindex int8engine *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)}// cookiefunc (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克隆一遍,将路径和处理函数合并一下。
