第一个程序
一般写程序都是从hello world开始的,既然学习gin框架那么我也是从hello world开始,直接看下面的demo
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"hello": "world",
})
})
r.Run()
}
代码分析
下面我就从main函数里面的第一行开始分析吧
r := gin.Default()
从字面意思上理解先初始化个默认的实例,既然有默认的实例那么就有自定义的的实例 (r:=gin.New) ,这边先说说默认的实例。让我们看下Default()函数,下面是Default函数的源代码
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
可以看到Default函数中也用到的了New()方法去初始化实例,上面说的自定义实例也用到New()函数,那让我们看看New()里面做了什么
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
AppEngine: defaultAppEngine,
UseRawPath: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJsonPrefix: "while(1);",
}
engine.RouterGroup.engine = engine
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine
}
其实很简单,初始化了个Engine,engine := &Engine{},Engine是一个结构体,具体属性基本都有注释,打开Engine结构体便知道什么意思 Default函数如下行代码,定义了全局的中间件Logger,Recovery。
engine.Use(Logger(), Recovery())
这也是我觉得gin做的比较好的地方,模块化!
下面几行代码是定义路由和路由对应的handler,Context作为上下文,贯穿整个请求,gin对响应内容格式做了很多处理,JSON,XML,YAML等等
r.GET("/hello", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"hello": "world",
})
})
最后一行代码
r.Run()
启动程序,默认是开启8080端口,也可以自定义端口r.Run("8088") ,因为gin使用了go原生的net/http包,所以启动也是用http下的http.ListenAndServe(address, engine)函数!
总结
从第一行代码到最后一行代码,可以看出gin使用的基本上是go原生net/http包下暴露处出函数和接口,非常的轻量级和简单。而且很方便的自定义中间件也显得gin是个非常灵活的框架。