hello world
使用Gin实现Hello world非常简单,创建一个router,然后使用其Run的方法:
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main(){
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World")
})
router.Run(":8000")
}
- Default函数
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
函数返回一个默认的框架引擎,从函数实现可以看到,首先是一个版本golang版本检查的日志输出(默认函数),接下来创建了一个最简单的引擎, 引擎中注册两个中间件,写标准日志的、panic recover的, 引擎注册的中间件都是 type HandlerFunc func(*Context) 类型,这个点很值得借鉴。
- 路由
首先引擎Engine结构定义可以看出它是组合继承了RouterGroup结构,所以引擎对象也同样是一个路由对象
type Engine struct {
RouterGroup
// Enables automatic redirection if the current route can't be matched but a
// handler for the path with (without) the trailing slash exists.
// For example if /foo/ is requested but a route only exists for /foo, the
// client is redirected to /foo with http status code 301 for GET requests
// and 307 for all other request methods.
RedirectTrailingSlash bool
......
}
如上所示,才有了router.GET(...)的成立,下面我们分析路由RouterGroup这个结构即其特性
type RouterGroup struct {
Handlers HandlersChain
basePath string
engine *Engine
root bool
}
如上,RouterGroup仍然可以拥有自己的engine属性,虽然engine组合继承了RouterGroup,还好这个属性是私有的,限制了其使用范围
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
RouterGroup 实现了如下方法 包括常见的get post delete 等
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
StaticFile(string, string) IRoutes
Static(string, string) IRoutes
StaticFS(string, http.FileSystem) IRoutes
}
从上面的接口可以看出,路由方法都是由 路径+处理函数 两个参数构成,在执行GET 、POST函数时,其实就是在注册 对应路径应该使用哪个处理函数来处理,经过进一步查看handle方法,框架是以调用方法来组织的 ,一种方法一个root ,root是一个node数组,node数组元素就是具体的路由路径和处理函数,具体结构如下
//路由树
type methodTrees []methodTree
RouterGroup struct {
...
trees methodTrees
...
}
//每个方法的item
type methodTree struct {
method string
root *node
}
//路由映射item
type node struct {
path string
indices string
children []*node
handlers HandlersChain
priority uint32
nType nodeType
maxParams uint8
wildChild bool
fullPath string
}
有疑问加站长微信联系(非本文作者)