Go小课03Gin Simple Demo解读
一、概述
1、简介
- Go官方为了支持Web开发,提供了
net/http
工具包;但是在实际项目中,团队还是会选择更加高效,更便捷的Web框架,如Gin
、Echo
,Beego
等; - 在这些团队中,很多团队选择了
Gin
这个框架,它在net/http
的基础上做了优化;对比其他主流框架,它更好的性能和更快的路由;
2、Gin的优点
-
快速:基于
Radix
树的路由,性能非常强大。 -
支持中间件:内置许多中间件,如
Logger
,Gzip
,Authorization
等。 -
崩溃恢复:可以捕捉panic引发的程序崩溃,使Web服务可以一直运行。
-
JSON验证:可以验证请求中
JSON
数据格式。 -
路由分组:支持路由分组(
RouteGroup
),可以更方便组织路由。 -
错误管理机制:可以收集程序中的错误
-
多种数据渲染方式:支持
HTML
、JSON
、YAML
、XML
等数据格式的响应。 -
扩展性:非常简单扩展中间件。
-
数据验证器:支持数据验证器且可以自定义。
3、Gin Simple Demo
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func setupRouter() *gin.Engine {
r := gin.Default()
// Ping test
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status" : 0,
"msg" : "success",
"data" : gin.H {
"content" : "pong",
},
})
})
return r
}
func main() {
r := setupRouter()
r.Run()
}
二、Gin Simple Demo 解读
从Demo Code可以看出,使用Gin的体验非常顺滑,定义处理Web请求就四步:导入包、定义路由、编写 Handler、监听端口。
1. 导入包
import "github.com/gin-gonic/gin"
2. 定义路由
- gin.Engine是路由引擎,一般使用
gin.Default()
方法创建并返回gin.Engine实例
.
r := gin.Default() //r默认使用了Logger和Recovery两个中间件
说明:可以用gin.New()
方法创建并返回一个不包含任何中间件的gin.Engine实例
3. 编写 Handler
通过默认路由,我们可以创建处理HTTP请求的方法,示例中使用GET方法:
// Ping test
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status" : 0,
"msg" : "success",
"data" : gin.H {
"content" : "pong",
},
})
})
- Get方法底层实现是调用
RouterGroup
的handle
方法, 请求的处理是使用HandlerFunc
类型方法
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle("GET", relativePath, handlers)
}
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
- 说明:Gin支持所有通用的HTTP请求方法,如
GET
,POST
,PUT
,PATCH
,OPTIONS
,HEAD
,DELETE
。
4. 监听端口
- 定义好请求之后,使用Run()方法便可监听端口,开始接受HTTP请求,如果Run()方法没有传入参数的话,则默认监听8080端口。
r.Run()
- Run方法的底层实现关键是:
http.ListenAndServe
,其中:http来自net/http
包。
func (engine *Engine) Run(addr ...string) (err error) {
defer func() { debugPrintError(err) }()
address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
//
err = http.ListenAndServe(address, engine)
return
}
三、Gin中重要数据结构
在Gin Simple Demo Code中,我们发现了三个重要的Go数据结构:gin.Engine
、gin.Context
和 gin.RouterGroup
1、gin.Engine
- gin.Engine 是框架的入口;我们通过 Engine 对象来定义服务路由信息、组装插件、运行服务,整个 Web 服务的都是由它来驱动的。
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
// Create an instance of Engine, by using New() or Default()
type Engine struct {
RouterGroup
//....
}
- gin.Engine本质是对内置的 HTTP 服务器的包装,让它使用起来更加便捷。
- gin.Default() 函数会生成一个默认的 Engine 对象,里面包含了 2 个默认的常用插件,分别是 Logger 和 Recovery,Logger 用于输出请求日志,Recovery 确保单个请求发生 panic 时记录异常堆栈日志,输出统一的错误响应(
推荐使用
)。
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
- gin.New()函数会生成一个默认的 Engine 对象,不包含任何中间件的gin.Engine实例。
2、gin.Context
- 请求的上下文信息对象,它是所有请求Handler的入口参数。
gin.Context
的结构定义如下:
// Context允许我们在中间件之间传递变量,管理流程,验证请求的JSON,并返回JSON
type Context struct {
//请求对象
Request *http.Request
// 用来响应
writermem responseWriter
Writer ResponseWriter
// URL里面的参数,比如:/xx/:id
Params Params
// 参与的处理者(中间件 请求处理者列表)
handlers HandlersChain
// 当前处理到的handler的下标
index int8
fullPath string
// Engine单例
engine *Engine
// 在context可以设置的值
Keys map[string]interface{}
// 一系列的错误
Errors errorMsgs
//为内容协商定义一组手动接受的格式。
Accepted []string
// queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query()
queryCache url.Values
// formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH,
// or PUT body parameters.
formCache url.Values
}
- Context这个上下文对象不是每次生成,而是从对象池里面取出来的;而请求的真正处理核心在
handleHTTPRequest
函数中。 - handleHTTPRequest函数中的核心逻辑:根据请求方法和请求的URI,找到并调用 处理的函数数组(包括我们定义的处理函数,还有中间层的处理函数)。
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// 从对象池中获取一个context对象
c := engine.pool.Get().(*Context)
// 初始化上下文对象,因为从对象池取出来的数据,有脏数据,故要初始化。
c.writermem.reset(w)
c.Request = req
c.reset()
//处理web请求 (http请求处理)
engine.handleHTTPRequest(c)
//将Context对象扔回对象池了
engine.pool.Put(c)
}
3、gin.RouterGroup
- RouterGroup是路由分组,是对路由树的包装,所有的路由规则最终都是由它来进行管理。Engine 结构体继承了 RouterGroup ,所以 Engine 直接具备了 RouterGroup 所有的路由管理功能。
// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
Handlers HandlersChain
basePath string
engine *Engine
root bool
}
// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc
-
RouteGroup 对象中主要包括:
basePath
(前缀路径)、Engine 指针
和Handlers
(处理函数数组)。 -
RouterGroup 实现了 IRouter 接口定义的一系列路由方法;这些方法最终都是通过调用 Engine.addRoute 方法将请求处理器挂接到路由树中。
-
RouterGroup 内部有一个前缀路径属性,它会将所有的子路径都加上这个前缀再放进路由树中。有了这个前缀路径,就可以实现 URL 分组功能。Engine 对象内嵌的 RouterGroup 对象的前缀路径是 /,它表示根路径。RouterGroup 支持分组嵌套,使用 Group 方法就可以让分组下面再挂分组。
v1 := r.Group("/api/v1") { v1.POST("/submit",submit) v1.GET("/list",list) } // Engine对象中RouterGroup对象是第一层分组(根分组),v1是根分组的子分组。
4、gin.H
- gin.H 是 map[string]interface{} 的一个快捷名称.
type H map[string]interface{}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhbebjfb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24