go-gin源码(一)


本文摘自网络,作者,侵删。

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
}

本文来自:简书

感谢作者:day_after_day

查看原文:go-gin源码(一)

相关阅读 >>

分享Go命名规范小记

Golang中“=”与“:=”的区别

2021-03-18 Golang 以太坊大额转账转换问题

Golang程序设计——函数

Golang调用cmd命令时如何隐藏dos窗口

手撸Golang 架构设计原则 单一职责原则

Go基础编程:数据类型

n皇后问题(Go版本)

手撸Golang Go与微服务 saga模式之7

Golang可以调用lua吗?

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...