gin路由源码

  1. // POST is a shortcut for router.Handle("POST", path, handle).
  2. func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {
  3. return group.handle("POST", relativePath, handlers)
  4. }
  5. // GET is a shortcut for router.Handle("GET", path, handle).
  6. func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
  7. return group.handle("GET", relativePath, handlers)
  8. }
  9. // DELETE is a shortcut for router.Handle("DELETE", path, handle).
  10. func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
  11. return group.handle("DELETE", relativePath, handlers)
  12. }
  13. // PATCH is a shortcut for router.Handle("PATCH", path, handle).
  14. func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes {
  15. return group.handle("PATCH", relativePath, handlers)
  16. }
  17. // PUT is a shortcut for router.Handle("PUT", path, handle).
  18. func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes {
  19. return group.handle("PUT", relativePath, handlers)
  20. }
  21. // OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle).
  22. func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes {
  23. return group.handle("OPTIONS", relativePath, handlers)
  24. }
  25. // HEAD is a shortcut for router.Handle("HEAD", path, handle).
  26. func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes {
  27. return group.handle("HEAD", relativePath, handlers)
  28. }
  29. // Any registers a route that matches all the HTTP methods.
  30. // GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
  31. func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
  32. group.handle("GET", relativePath, handlers)
  33. group.handle("POST", relativePath, handlers)
  34. group.handle("PUT", relativePath, handlers)
  35. group.handle("PATCH", relativePath, handlers)
  36. group.handle("HEAD", relativePath, handlers)
  37. group.handle("OPTIONS", relativePath, handlers)
  38. group.handle("DELETE", relativePath, handlers)
  39. group.handle("CONNECT", relativePath, handlers)
  40. group.handle("TRACE", relativePath, handlers)
  41. return group.returnObj()
  42. }

gin支持 POST、GET、DELETE、PATCH、PUT、OPTIONS、HEAD、Any方法
常用的restful api的方法都支持,可以放心大胆的做reful api开发。最后的Any方法可以就收任何请求。

添加路由

  1. r := gin.Default()
  2. r.GET("/ping", func(c *gin.Context) {
  3. c.JSON(200, gin.H{
  4. "message": "pong",
  5. })
  6. })

第一行代码,创建了一个gin的实例对象,
然后用这个gin实例对象 r.GET()就可以注册一个GET请求。
其他类型的请求也只需要再写r.POST(),r.DELETE()…就行。
这些方法接受2个参数,
一个是路由对应的路径,👆🌰中,就是”/ping”,访问127.0.0.1:8080/ping即可访问到次路由。
第二个参数是一个处理函数,用来处理路由的请求。
此处理函数一定要接受gin.Context的指针 c,就是一个gin的上下文。
来看下gin.Context的源码

  1. //上下文是gin的重要概览。它允许我们在中间件之间传递变量,
  2. //例如,管理流、验证请求的JSON并呈现JSON响应。
  3. type Context struct {
  4. writermem responseWriter
  5. Request *http.Request
  6. Writer ResponseWriter
  7. Params Params
  8. handlers HandlersChain
  9. index int8
  10. engine *Engine
  11. // Keys is a key/value pair exclusively for the context of each request.
  12. Keys map[string]interface{}
  13. // Errors is a list of errors attached to all the handlers/middlewares who used this context.
  14. Errors errorMsgs
  15. // Accepted defines a list of manually accepted formats for content negotiation.
  16. Accepted []string
  17. }

gin.Context是一个结构体,它包含很多东西,例如gin的实例:engine Engine,请求内容:Request http.Request,请求参数:Params Params等等。
不仅如此,gin.Context还有很多方法,常用的有:

  1. // 用于获取路径参数
  2. func (c *Context) Param(key string) string {
  3. return c.Params.ByName(key)
  4. }
  5. // 用于获取query参数 GET /path?id=1234&name=Manu&value=
  6. func (c *Context) Query(key string) string {
  7. value, _ := c.GetQuery(key)
  8. return value
  9. }
  10. //请求头
  11. func (c *Context) Header(key, value string) {
  12. if value == "" {
  13. c.Writer.Header().Del(key)
  14. return
  15. }
  16. c.Writer.Header().Set(key, value)
  17. }
  18. // cookie
  19. func (c *Context) Cookie(name string) (string, error) {
  20. cookie, err := c.Request.Cookie(name)
  21. if err != nil {
  22. return "", err
  23. }
  24. val, _ := url.QueryUnescape(cookie.Value)
  25. return val, nil
  26. }
  27. // JSON serializes the given struct as JSON into the response body.
  28. // It also sets the Content-Type as "application/json".
  29. func (c *Context) JSON(code int, obj interface{}) {
  30. c.Render(code, render.JSON{Data: obj})
  31. }

基本上,常用的处理请求的方法都挂载到context上,这样方便我们进行数据传递和处理请求。

路由分组

使用g实例的Group来进行分组

  1. g:=gin.New()
  2. u:=g.Group("/v1")
  3. {
  4. u.POST("/user", user.Create) // 创建用户
  5. u.DELETE("/user/:id", user.Delete) // 删除用户
  6. u.PUT("/user/:id", user.Update) // 更新用户
  7. u.GET("/user", user.List) // 用户列表
  8. u.GET("/user/:username", user.Get) // 获取指定用户的详细信息
  9. }

这样,大括号内的路由前面都添加了一个/v1的路由,方便我们对路由进行分组和版本控制

看一下g.Group()的源码:

  1. // Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
  2. // For example, all the routes that use a common middleware for authorization could be grouped.
  3. func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
  4. return &RouterGroup{
  5. Handlers: group.combineHandlers(handlers),
  6. basePath: group.calculateAbsolutePath(relativePath),
  7. engine: group.engine,
  8. }
  9. }

g.Group()返回一个新的gin路由群*RouterGroup,将原来的gin实例engine克隆一遍,将路径和处理函数合并一下。