Web开发学习手记(四):MongoDB及mgo
前言 在学习手记(三)中的实例——简单的用户系统中,使用了MongoDB管理用户数据。这篇 …
May all the beauty be blessed.
冰岩作坊的各种产品都与互联网相关,不可避免地会用到Go语言的网络框架,其中,gin就是一个使用广泛的框架。
新人任务中,我用gin完成了若干实例的开发,学习了gin的一些使用方法。这篇文章整理了我接触过的部分功能。由于使用的场景有限,这里只列举了有限的几个内容。
Router,即路由器(不是一个小盒子那个),功能是监听某个端口的HTTP请求,并根据请求的URL用不同的Handler处理。
在gin中,可以通过gin.Default()
获得一个Router,它的类型是gin.Engine
。你可以将Handler和Middleware添加到这个Router上,使它按照规则处理请求。
对于Handler,你可以通过Router的GET、POST等方法绑定对于某一类型请求的Handler函数,并指定绑定的URL。
对于Middleware,你可以通过Router的Use方法绑定一个Middleware函数。一般在使用Middleware的时候,常常使用Group对某一URL的请求分类,在绑定Middleware的同时绑定Handler。
Handler,即处理函数,功能是处理指定的请求,并根据请求给出相应的响应。
在gin中,Handler应当是一个接受一个*gin.Context
类型参数的函数。使用JSON进行C/S通信是一种很常用的方法,你可以通过gin.Context
的BindJSON
方法将请求体中的JSON内容解析进指定结构体中。结构体内的变量需要设置json反射标签。以下给出一个使用例。
type ReqType struct {
var Data int `json:"data"`
}
func main() {
router := gin.Default()
router.POST("/", func(context *gin.Context) {
var req ReqType
err := context.BindJSON(&req)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(req.Data)
})
_ = router.Run()
}
gin也可以很方便地使用JSON作出响应。gin.H
是一个对map的简写,你可以用它简单地创建一个map,并用context.JSON
方法作出响应。以下给出一个使用例。
type ReqType struct {
var Data int `json:"data"`
}
func main() {
router := gin.Default()
router.POST("/", func(context *gin.Context) {
var req ReqType
err := context.BindJSON(&req)
if err != nil {
fmt.Println(err.Error())
return
}
context.JSON(http.StatusOK, gin.H{
"message": req.Data,
})
})
_ = router.Run()
}
Handler还可以处理其他类型的请求,如GET、OPTIONS等,由于我没有接触过这些请求的用法,这里便留空了。
Middleware,即中间件,功能是在请求发给Handler之前对请求进行一些处理,比如验证权限。在我的实践中,我实现了一个验证JWT的Middleware,用于API的认证。
gin中提供了router.Group
这一方法,可以对Router的某一URL进行多个操作,例如绑定Middleware和绑定Handler。可以先用router.Group
获取到一个RouterGroup,然后用group.Use
绑定一个Middleware。
Middleware的实现是一个接受一个*gin.Context
类型的参数的函数。在这个函数中,你可以分析请求,如果需要拒绝请求,使用context.Abort
方法,如果请求可以继续处理,使用context.Next
方法。以下是一个使用Middleware对API做简单验证的例子。
type ReqType struct {
var Pass int `json:"pass"`
}
func main() {
router := gin.Default()
api := router.Group("/api")
api.Use(func(context *gin.Context) {
var req ReqType
err := context.BindJSON(&req)
if err != nil || req.Pass != "password" {
context.JSON(http.StatusUnauthorized, gin.H{
"error": "error!",
})
context.Abort()
return
}
context.Next()
})
api.POST("/", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"message": "welcome",
})
})
_ = router.Run()
}