为了以后的开发便利,这里添加一个gin的框架结构。

gin现在已经有自己的中文帮助手册,那直接参考它的中文手册就好了,文档

https://github.com/younglifestyle/goexamples/tree/master/gin-demo

gin中还有对session的中间库,很多中间库和beego很类似,还是很方便的。

gin HTTP Server启动时自定义参数

例如:

1
2
3
4
func main() {
router := gin.Default()
http.ListenAndServe(":8080", router)
}
1
2
3
4
5
6
7
8
9
10
11
12
func main() {
router := gin.Default()

s := &http.Server{
Addr: ":8080",
Handler: router,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
s.ListenAndServe()
}

参数支持

gin可以直接对URL query、json以及form进行序列化。

1
2
3
4
// 使用gin可以猜测传递的参数
var tmp interface{}
c.ShouldBind(&tmp)
c.Bind(&tmp)

json Tag

binding:"required",gin框架会对此tag进行检查,添加后,意味着在接受数据时,query、表单或者body中必须要匹配到该字段。

1
2
3
4
type UserToken struct {
UserId string `json:"userid" form:"userid" binding:"required"`
Token string `json:"token" form:"token" binding:"required"`
}

请求中使用Goroutine

在中间件或处理程序中启动新的Goroutines时,不应该使用其中的原始上下文,必须使用只读副本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func main() {
r := gin.Default()

r.GET("/long_async", func(c *gin.Context) {
// create copy to be used inside the goroutine
cCp := c.Copy()
go func() {
// simulate a long task with time.Sleep(). 5 seconds
time.Sleep(5 * time.Second)

// note that you are using the copied context "cCp", IMPORTANT
log.Println("Done! in path " + cCp.Request.URL.Path)
}()
})

r.GET("/long_sync", func(c *gin.Context) {
// simulate a long task with time.Sleep(). 5 seconds
time.Sleep(5 * time.Second)

// since we are NOT using a goroutine, we do not have to copy the context
log.Println("Done! in path " + c.Request.URL.Path)
})

// Listen and serve on 0.0.0.0:8080
r.Run(":8080")
}