gin
入参绑定
Bind
根据 Content-Type 可以自动绑定参数,优先绑定 body 中的 Json 或 Form,然后绑定 QueryString。
Bind 如果绑定失败,会返回400状态码,且设置 response 的header的 Content-Type 为 text/plain
ShouldBind 如果绑定失败,后续代码返回指定的 StatesCode 仍然可以生效,Content-Type 仍然是默认的 application/json
ShouldBindJSON
仅匹配 body 传 Json 类型的参数,不绑定 Form 和 QueryString。BindJSON 方法的特性类似如上。
路由
gin框架采用了httprouter进行路由匹配,httprouter 是通过基数树(radix tree)来进行高效的路径查找。
前缀树(trie),是一个多叉树,广泛应用于字符串搜索,每个树节点存储一个字符,从根节点到任意一个叶子结点串起来就是一个字符串;基数树(radix tree)是优化之后的前缀树,对空间进一步压缩,如果该节点是唯一的子树,就和父节点合并。

假设有以下路由信息:
那么我们会得到一个GET方法对应的路由树,具体结构如下:(路由器为每种请求方法管理一棵单独的树,还有POST、PUT、DETELE等)
每个树级别上的子节点都按Priority(优先级)排序,其中优先级(最左列)就是在子节点(子节点、子子节点等等)中注册的句柄的数量,短路径查找速度快,这样设计可以让尽可能多的路由快速被定位。
使用基数树对比于直接用map做路由有什么优势?
路由有/user/:id这种有参数的类型,用map就不好匹配了,因此我们需要的是根据路由模式进行匹配,而不仅仅是比较哈希值。
路由树的节点类型:
static: 静态节点(默认),比如上面的s,earch等节点
root: 树的根节点
catchAll: 有*匹配的节点
param: 参数节点
中间件
可以使用应用于全局的中间件,也可以使用应用于某个路由组的中间件,可以使用中间件链按序执行。
c.Next()
c.Next() 仅可以在中间件中使用。c.Next() 会把函数链中挂起的函数(包括中间件和controller)都执行完毕再执行其后续代码,以此可以实现中间件链的嵌套调用,而不是默认的顺序调用。
c.Abort()
c.Abort() 阻止未执行的挂起函数继续被调用,未执行的中间件和controller都不再执行,已执行的函数还会继续执行其后续代码。
应用场景:在鉴权中间件中判断用户无权限之后调用c.Abort()。
c.Set() & c.Get()
中间件和controller都能使用,在不同的中间件和controller之间可以利用这2个函数来传值。
应用场景:在中间件中根据用户传递的cookie或token来判断用户身份,然后c.Set("userId", id)好,controller就可以调用c.Get("userId")直接取出来。
优雅关机
http.Server 内置的 Shutdown() 方法就支持优雅地关机
优雅重启
多台服务器,滚动发布,当1台服务器shutdown时,还有其他服务器可以为用户提供服务,逐个重启即可。
Last updated
Was this helpful?