简介
1 使用框架的http服务 和 路由
Gin强调性能,关注调用数、操作耗时、内存分配及分配次数。
核心组件gin.Engine
封装http.Server,提供默认的日志和恢复中间件。
路由管理通过RouterGroup实现,支持URL分组和命名参数。
Context
处理请求上下文,如参数、Cookie和Header。
通过Group
方法创建路由分组,注册API如/resource/{id}
。
2 框架简介
这里只对框架gin的需要用的功能做介绍如下:
框架性能评估
(1):在一定的时间内实现的总调用数,越高越好 (2):单次操作耗时(ns/op),越低越好 (3):堆内存分配 (B/op), 越低越好 (4):每次操作的平均内存分配次数(allocs/op),越低越好
性能横向对比链接
https://github.com/XFrankly/Comparative-performance-gin-vs-tornado
3 web框架使用步骤
1 设计 API 端点。
2 为您的代码创建一个文件夹。
3 创建数据。
4 编写一个处理程序以返回所有项目。
5 编写一个处理程序来添加一个新项目。
6 编写一个处理程序来返回一个特定的项目。
4 引擎介绍 gin.Engine
它使用GO的内置 http.Server 本质上是对 http server的封装,使用更便捷
gin.Default() 将创建一个默认的Engine对象,包括了Logger 和 Recovery
Logger 用于日志处理
Recovery确保单个请求发生panic时记录异常堆栈,输出统一错误信息
Engine的定义
func Default() *Engine {
engine := New()
engine.Use(Logger(), Recovery()) //使用两个中间件
return engine
}
而 gin.New() 将不使用默认的 Logger 和 Recovery
不使用默认的中间件
使用
r := gin.New()
代替
// Default 使用 Logger 和 Recovery 中间件
r := gin.Default()
如下示例 //结构体 ServerGroup 服务和路由分组用到
type ServerGroup struct {
*gin.Engine
}
创建一个引擎 并限制在写入磁盘之前多少内存占用 内存使用
func MakeNewEngine() *gin.Engine {
me := gin.New()
return me
}
作为Server的构造器 GroupServer的构造器 最后用作 链式调用
func NewServers(e *gin.Engine) *ServerGroup {
s := &ServerGroup{Engine: MakeNewEngine()}
if e != nil {
s.Engine = e
}
return s
}
5 路由和上下文处理
RouterGroup是对路由树的包装,所有路由规则最终都是由它管理,Engine结构体继承了RouterGroup,所以在Engine直接具备了RouterGroup所有的路由管理功能。
RouterGroup包括一个Engine指针
type Engine struct {
RouterGroup
....
}
type RouterGroup struct {
...
engine *Engine
...
}
RouterGroup 实现了IRouter接口,暴露了一系列路由方法,这些方法最终通过调用Engine.addRoute方法将请求处理器挂接到路由树
GET(string, ...HandlerFunc) IRoutes
POST...
...
//匹配所有的HTTP Method
Any(string, ...HandlerFunc) IRoutes
RouterGroup有一个前缀路径属性,它将所有子路径都加上前缀 再放入路由树。
有了这个前缀就可以实现URL分组功能。
Engine对象内嵌的RouterGroup的对象前缀路径是/ 它表示根路径
RouterGroup支持分组嵌套,使用Group方法就可让分钟下面再挂分组。
路由树,路由规则分成最多9棵前缀树,每个 HTTP Method对应一颗 前缀树
树的节点按 URL中的/符号层级划分,
URL支持 :name形式的名称匹配,
还支持 *subpath形式路径通配符
path = /book/:id
match /book/13
Context负责处理请求的上下文信息。它是所有请求处理器的入口参数,负责处理请求中的URL参数,Cookie,Header等
// 路由注册,组名称 查询列表 具体信息
func SetupRouters(sg *gin.RouterGroup) {
lives := sg.Group("/resource")
lives.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "success", "data": "welcome!", "code": 200,
})
})
lives.GET("/list", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "success", "data": vdata, "code": 200,
})
})
lives.GET("/:id", func(c *gin.Context) {
id := c.Param("id")
var data map[string]string
for _, v := range vdata {
if id == v["id"] {
data = v
}
}
c.JSON(http.StatusOK, gin.H{
"message": "success", "data": data, "code": 200,
})
})
}
绑定路由到引擎
func NewRouter() http.Handler {
RS.Routers()
SetupRouters(Router)
return RS
}
6 Json响应
Gin 使用 encoding/json 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 jsoniter。
go build -tags=jsoniter .
使用内置的响应方式
c.JSON(http.StatusOK, gin.H{
"message": "success", "data": "welcome!", "code": 200,
}