gin设计、性能虽然很优秀,但是它内置功能过于简单,无法直接拿来开发项目,他没有操作数据库ORM、没有接口拦截等功能。但因其简洁、高性能而备受青睐,还有其中间件设计可以让开发者在其基础上扩展各种功能,这也是其框架优秀地方。我们Gin框架优秀基础功能上集成适合自己所需框架,这样也能更好契合自己的开发习惯,进而提高开发效率。
我们有多年Java、C#、PHP开发经验,把这些语言使用过好的功能设计等功能列出来,再结合Go语言特性,目标是做出一个安全可靠、高性能、高效率、低成本、易学的框架来,经过多年项目实战不断更新,终于得到心中所想的框架。下面我们把框架几个我们认为很不错设计分享出来,希望有和我们一样目标的朋友,做框架或项目时可借鉴一下。
框架设计
框架基础的jwt、cors、api限流、静态资源访问路径处理等基础功能就不细说了这个网上有很多。我和大家讲目录结构设计、api接口路由自动生成和ORM使用。
目录结构设计
用过gin框架的朋友应该知道接口的请求路由是要手动添加到router(gin.Default())中的,为了让框架能自动生成api接口路由和开发功能模块层次清晰,在目录结构上我们严格设计规则,有了统一规则这样框架才方便多人协同开发。
应用开发在app目录下,目录结构分类两层,在app目录第一层目录为应用模块,在应用模块目录下(即app目录下第二层)为功能类。每一层我们设置一个controller.go控制器,其中第一层控制器是用来控制模块引入,第二层控制器是用来控制功能类引入。
每一个模块都可以添加一个RouterHandler路由中间件/路由钩子用了编写每个模块自己整个模块接口请求前拦截或者数据统一处理。设计为第一层controller.go控制器可以添加底层RouterHandler第二层controller.go控制器RouterHandler。如果目录不需处理自己模块路由中间件,则第一层controller.go控制器的RouterHandler无需添加对应模块路由中间件RouterHandler。
开发时如何使用模块和功能类这两层设计呢?我们把大的功能合并为一个模块,例如:admin后台管理、business后台管理、app、微信小程序、抖音小程序等这样功能做成一个模块。功能类是模块内一个功能,例如:business后台管理的文章管理、系统设置、商城管理、微信管理等模块中一个相关性集中功能作为一个类,而且一个类内可以添加多个.go文件来写对应功能接口,例如:商城管理可以分:product.go产品管理、product_cate.go产品分类、ordor.go订单管理等等,这样开发时就可以无限扩展,代码层级有清晰易读。
通过代码规范分成我们设计的框架就可以根据层级生成对应api接口路由。接口请求路由自动生成不仅减少开发工作量同时避免手动添加名不规范且出现重名导致程序错误。
ORM调用
框架封装完善的数据库操作功能,在编写接口时直接gf.Model("数据表名称")调用。下面给处 更新、删除、获取内容的接口代码示例:
- 更新数据操作
// 更新状态
func (api *Product) UpStatus(c *gf.GinCtx) {
param, _ := gf.RequestParam(c)
res2, err := gf.Model("createcode_product").Where("id", param["id"]).Data(param).Update()
if err != nil {
gf.Failed().SetMsg("更新失败!").SetData(err).Regin(c)
} else {
msg := "更新成功!"
if res2 == nil {
msg = "暂无数据更新"
}
gf.Success().SetMsg(msg).SetData(res2).Regin(c)
}
}
- 删除数据操作
// 删除
func (api *Product) Del(c *gf.GinCtx) {
param, _ := gf.RequestParam(c)
res2, err := gf.Model("createcode_product").WhereIn("id", param["ids"]).Delete()
if err != nil {
gf.Failed().SetMsg("删除失败").SetData(err).Regin(c)
} else {
gf.Success().SetMsg("删除成功!").SetData(res2).Regin(c)
}
}
- 获取一条数据
// 获取内容
func (api *Product) GetContent(c *gf.GinCtx) {
id := c.DefaultQuery("id", "")
if id == "" {
gf.Failed().SetMsg("请传参数id").Regin(c)
} else {
data, err := gf.Model("createcode_product").Where("id", id).Find()
if err != nil {
gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c)
} else {
gf.Success().SetMsg("获取内容成功!").SetData(data).Regin(c)
}
}
}
好了,分享结束,希望对你集成Gin框架有所启发。
如果想体验我们框架可以点击这里:在线体验