Gin 是一个用 Golang 编写的 Web 框架。具有速度快、内存占用小等特点。


使用 Gin

  1. 下载并安装 Gin:
$ go get -u github.com/gin-gonic/gin
  1. 引入 Gin:
import "github.com/gin-gonic/gin"

如果需要使用诸如 http.StatusOK 之类的 HTTP 状态码常量,可以引入 net/http 包:

import "net/http"
  1. 开始使用 Gin。

main.go

package main

import "github.com/gin-gonic/gin"

func main() {
  // 获取 gin.Engine 实例
  routers := gin.Default()

  // 接收 GET /hello 请求
  routers.GET("/hello", func(ctx *gin.Context) {
    ctx.JSON(200, gin.H{
      "message": "Hello World!",
    })
  })

  // 捕获并记录错误
  defer func() {
    if err := recover(); err != nil {
      logrus.Error(err)
    }
  }()

  // 监听并在 0.0.0.0:8080 上启动服务(默认即为 8080)
  if err := routers.Run(":8080"); err != nil {
    panic(err)
  }
}

接着运行:

$ go run main.go

或者,运行以下命令也可获取 Gin 官方代码示例:

$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go

Gin 请求

在如上示例中,使用 routers.GET() 创建了一个接收 GET /hello 请求的路由,并且绑定了其路由的处理函数。GET() 的定义如下:

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

其中:

  • RouterGroup:即 gin.RouterGroup。表示一个路由组实例。

    由于 gin.Engine 继承了 gin.RouterGroup,所以 gin.Engine 本质上也是一个路由组实例。

    type Engine struct {
      RouterGroup
    
      // ...
    }
    
  • relativePath:表示路由接收的请求相对路径。例如 /hello

  • handlers:是一系列请求处理函数 HandlerFunc。在 GET() 中可以指定多个 HandlerFunc,它们将按照指定的顺序执行。中间件(middleware)、过滤器(filter)、拦截器(interceptor)等,可以基于此进行实现。

  • IRoutes:定义了一系列路由请求方法。

    type IRoutes interface {
      Use(...HandlerFunc) IRoutes
    
      Handle(string, string, ...HandlerFunc) IRoutes
      Any(string, ...HandlerFunc) IRoutes
      GET(string, ...HandlerFunc) IRoutes
      POST(string, ...HandlerFunc) IRoutes
      DELETE(string, ...HandlerFunc) IRoutes
      PATCH(string, ...HandlerFunc) IRoutes
      PUT(string, ...HandlerFunc) IRoutes
      OPTIONS(string, ...HandlerFunc) IRoutes
      HEAD(string, ...HandlerFunc) IRoutes
      Match([]string, string, ...HandlerFunc) IRoutes
    
      StaticFile(string, string) IRoutes
      StaticFileFS(string, string, http.FileSystem) IRoutes
      Static(string, string) IRoutes
      StaticFS(string, http.FileSystem) IRoutes
    }
    

    通过返回 IRoutes,可以使用链式调用风格来配置路由或中间件。

Gin 除了 Get 请求之外,还有可以配置其它请求方式,它们的使用方式差距不大:

func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodPost, relativePath, handlers)
}

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodDelete, relativePath, handlers)
}

func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodPatch, relativePath, handlers)
}

func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodPut, relativePath, handlers)
}

func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodOptions, relativePath, handlers)
}

func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodHead, relativePath, handlers)
}