首先我先推荐一篇很好的go-gin基础讲解
我在自己项目中go-gin的运用,从项目结构说起
- common 通用方法,全局变量
- config 配置文件
- controller mvc的c,写router的控制方法
- database 数据库连接
- middleware 中间件
- model mvc的m,声明结构体,数据处理(使用数据库)
- router 路由
- utiles 工具类方法(时间,加密之类方法的封装)
- mian 入口
这样一个相对通用简单的web项目结构搞好了,之后就是代码填充了。为什么谈go-gin却讲项目结构呢?因为在我的项目中只有router和controller中用到了go-gin。前后端分离所以这边没有搞view,也就用不到框架的一些功能。
go-gin在router中的使用
// Init 初始化路由func Init() { router := gin.Default() // CrossDomain跨域处理,options请求处理 router.Use(middleware.CrossDomain()) // v1群组对任何人开放 v1 := router.Group("/v1") { v1.POST("/login", user.Login) v1.POST("/register", user.Register) v1.GET("/index", index.GetInfo) v1.GET("/posts", post.GetPosts) v1.GET("/post", post.GetPost) } v2 := router.Group("/v2") // v2群组使用中间件AuthMiddleWare,需要token权限才能请求到 v2.Use(middleware.AuthMiddleWare()) { v2.POST("/publish", post.Publish) v2.POST("/isload", user.IsLoad) v2.POST("/reply1", post.Reply1) v2.POST("/reply2", post.Reply2) } router.Run(":8000")}复制代码
大写Init可以在main中决定何时调用,小写init自动初始化。gin.Default()得到路由对象,router.Use在总路由上挂一个中间件,此中间件的功能是解决跨域和options请求问题,所有前端请求必须经过这个中间件。v1,v2是定义的两个路由组,我在v2组上挂了需要token验证的中间件,v1组没有挂中间件对所有人开放。v1和v2下有一对大括号没有实际作用只用来修饰代码格式。请求方法中的第二个参数在controller中定义。 最后Run一个后端服务的端口。
model中声明结构体
例:
// Reply1 .type Reply1 struct { ID bson.ObjectId `json:"id"` ShareMsg `bson:",inline"`}// Reply2 .type Reply2 struct { ID bson.ObjectId `json:"id"` RID bson.ObjectId `json:"rid"` RName string `json:"rName"` Show bool `json:"show"` ShareMsg `bson:",inline"`}// ShareMsg .type ShareMsg struct { HeadImg string `json:"headImg"` UName string `json:"uName"` CreateTime string `json:"createTime"` Content string `json:"content"` TID bson.ObjectId `json:"tid"`}复制代码
代码在粘贴的过程中格式乱了,将就看。这边写了一些json的标签,对应的名称跟前端请求的json对象中的属性名一致(很关键)。这边简单讲一下bson:",inline"
标签,如果用的是mongodb,在保存对象的时候ShareMsg将以对象嵌套的形式保存在数据库中,使用该标签可以不嵌套,子结构体中的属性直接内联保存在父结构体中。这边还用到了bson.ObjectId类型,bson中有一个方法可以生成一个相对唯一的id,使用方便,需要该类型来接收。
go-gin在controller中的使用
// Reply1 一级回复func Reply1(c *gin.Context) { reply1 := &model.Reply1{} if err := c.Bind(reply1); err != nil { fmt.Println(err.Error()) return } reply1.UName = c.Request.Header["Authorization"][0] reply1.CreateTime = utils.GetTimeStr() reply1.ID = bson.NewObjectId() if reply1.Save(reply1.TID) { c.JSON(http.StatusOK, gin.H{ "reply": *reply1, }) } else { c.String(http.StatusOK, "内部错误") }}复制代码
- 定义结构体对象reply1,使用c.Bind(reply1)将前端传输的json对象与后端结构体对象完美绑定,其中后端定义了前端没有的属性时,数据类型默认为0,其他为空。 具体使用方法自行查找。
- 前端没有传json对象,用url或者表单参数请求,后端处理方法见文中开头,不细说了。
- 返回前端的请求,只要携带数据的我都用json对象返回,这边使用go-gin提供的方法详见代码中c.JSON这一段。如果只是简单告诉前端后端的一些状态直接c.String返回状态码和字符串。
对go-gin的个人使用介绍到此为止,有没有很精简?如果你有什么对go-gin更好的使用方法和意见请回复评论,或者有什么不理解的地方也可以与我一起探讨,下篇文中我打算写一点go中mgo的使用和采坑记录。