Go 框架三件套-Gin | 青训营笔记

406 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

1.Gin是什么

Gin 是一个 Go (Golang) 编写的轻量级 http web 框架,运行速度非常快,如果你是性能和高效的追求者,推荐你使用 Gin 框架。

Gin 最擅长的就是 Api 接口的高并发,如果项目的规模不大,业务相对简单,这个时候 也推荐使用 Gin。

当某个接口的性能遭到较大挑战的时候,这个还是可以考虑使用 Gin 重写接口。

Gin 也是一个流行的 golang Web 框架,Github Strat 量已经超过了 50k。

Gin 的官网: gin-gonic.com/zh-cn/

Gin Github 地址: github.com/gin-gonic/g…


2.Gin的功能特性

1.gin.Engine

Engine 是 Gin 框架最重要的数据结构,它是框架的入口。我们通过 Engine 对象来定义服务路由信息、组装插件、运行服务。

Engine 对象很简单,因为引擎最重要的部分 —— 底层的 HTTP 服务器使用的是 Go 语言内置的 http server,Engine 的本质只是对内置的 HTTP 服务器的包装,让它使用起来更加便捷。

gin.Default() 函数会生成一个默认的 Engine 对象,里面包含了 2 个默认的常用插件,分别是 Logger 和 Recovery,Logger 用于输出请求日志,Recovery 确保单个请求发生 panic 时记录异常堆栈日志,输出统一的错误响应。


2.路由树

在 Gin 框架中,路由规则被分成了最多 9 棵前缀树,每一个 HTTP Method对应一棵「前缀树」,树的节点按照 URL 中的 / 符号进行层级划分,URL 支持 :name 形式的名称匹配,还支持 *subpath 形式的路径通配符 。


3.gin.RouterGroup

RouterGroup 是对路由树的包装,所有的路由规则最终都是由它来进行管理。Engine 结构体继承了 RouterGroup ,所以 Engine 直接具备了 RouterGroup 所有的路由管理功能。

这是为什么在 Hello World 的例子中,可以直接使用 Engine 对象来定义路由规则。同时 RouteGroup 对象里面还会包含一个 Engine 的指针,这样 Engine 和 RouteGroup 就成了“你中有我我中有你”的关系。


4.gin.Context

这个对象里保存了请求的上下文信息,它是所有请求处理器的入口参数。

Context 对象提供了非常丰富的方法用于获取当前请求的上下文信息,如果你需要获取请求中的 URL 参数、Cookie、Header 都可以通过 Context 对象来获取。这一系列方法本质上是对 http.Request 对象的包装。

Context 对象提供了很多内置的响应形式,JSON、HTML、Protobuf 、MsgPack、Yaml 等。它会为每一种形式都单独定制一个渲染器。通常这些内置渲染器已经足够应付绝大多数场景,如果你觉得不够,还可以自定义渲染器。

所有的渲染器最终还是需要调用内置的 http.ResponseWriter(Context.Writer) 将响应对象转换成字节流写到套接字中。


5.插件与请求链

Gin 提供了插件,只有函数链的尾部是业务处理,前面的部分都是插件函数。在 Gin 中插件和业务处理函数形式是一样的,都是 func(*Context)。当我们定义路由时,Gin 会将插件函数和业务处理函数合并在一起形成一个链条结构。

Gin 在接收到客户端请求时,找到相应的处理链,构造一个 Context 对象,再调用它的 Next() 方法就正式进入了请求处理的全流程。

Gin 还支持 Abort() 方法中断请求链的执行,它的原理是将 Context.index 调整到一个比较大的数字,这样 Next() 方法中的调用循环就会立即结束。需要注意的 Abort() 方法并不是通过 panic 的方式中断执行流,执行 Abort() 方法之后,当前函数内后面的代码逻辑还会继续执行。

如果在插件中显示调用 Next() 方法,那么它就改变了正常的顺序执行流,变成了像洋葱一样的嵌套执行流。换个角度来理解,正常的执行流就是后续的处理器是在前一个处理器的尾部执行,而嵌套执行流是让后续的处理器在前一个处理器进行到一半的时候执行,待后续处理器完成执行后,再回到前一个处理器继续往下执行。

image.png

image.png


6.HTTP错误

当 URL 请求对应的路径不能在路由树里找到时,就需要处理 404 NotFound 错误。当 URL 的请求路径可以在路由树里找到,但是 Method 不匹配,就需要处理 405 MethodNotAllowed 错误。Engine 对象为这两个错误提供了处理器注册的入口


7.静态文件服务

这个对象里保存了请求的上下文信息,它是所有请求处理器的入口参数。

RouterGroup 对象里定义了下面三个用来服务静态文件的方法

// 服务单个静态文件 
StaticFile(relativePath, filePath string) IRoutes
// 服务静态文件目录 
Static(relativePath, dirRoot string) IRoutes 
// 服务虚拟静态文件系统 
StaticFS(relativePath string, fs http.FileSystem) IRoutes

8.表单处理

当请求参数数量比较多时,使用 Context.Query() 和 Context.PostForm() 方法来获取参数就会显得比较繁琐。Gin 框架也支持表单处理,将表单参数和结构体字段进行直接映射。

Context.ShouldBind 方法遇到校验不通过时,会返回一个错误对象告知调用者校验失败的原因。它支持多种数据绑定类型,如 XML、JSON、Query、Uri、MsgPack、Protobuf等,根据请求的 Content-Type 头来决定使用何种数据绑定方法。


9.HTTPS

Gin 不支持 HTTPS,官方建议是使用 Nginx 来转发 HTTPS 请求到 Gin。


3.Gin的路由

路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等) 组成的,涉及到应用如何响应客户端对某个网站节点的访问 ,RESTful API 是目前比较成熟的一套互联网应用程序的 API 设计理论,所以在设计路由的时候建议参考 RESTful API 指南,在 RESTful 架构中,每个网址代表一种资源,不同的请求方式表示执行不同的操作:

  • GET:从服务器取出资源(一项或多项)
  • POST:在服务器新建一个资源
  • PUT:在服务器更新资源(客户端提供改变后的完整资源)
  • DELETE:从服务器删除资源