「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战」
前言
由于才疏学浅,个人觉得前端暂时没有可以优化的地方了,现在来优化后端框架。因为后端框架基本上就是一个单文件和一些中间件,全局接口格式化的功能们,现在加一些路由层和服务曾,模型层组件,让它看起来更像一个商业的线上项目。
controller
是因为自己准备再加一个导航网站的增删改查的接口,所以必须再加几个接口。但是发现主文件太长了,所以就准备规范化一下这个框架。
在项目根目录下新建一个controller文件夹,新建一个controller.go
文件用于专门规范接口内容 输入一下内容:
package controller
import (
"main/global"
"main/service"
"github.com/gin-gonic/gin"
)
//规定一个控制器方法通过goloal规范化接口返回内容
func Api(c *gin.Context) {
result := global.NewResult(c)
data, err := service.Api()
if err != nil {
result.Error(5201, err.Error(), data)
return
}
result.Success(data)
}
复制代码
service
这里主要是调用model曾执行查询逻辑
package service
import (
"main/model"
)
func Api() (data interface{}, err error) {
list, nil := model.GetList()
return list, nil
}
复制代码
model
model层主要是做字段定义,连接初始化,连接关闭,模型查询方法。
package model
import (
"fmt"
"log"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gopkg.in/ini.v1"
)
var db *gorm.DB
func DbConnect() {
//配置文件路径
file, err := ini.Load("config.ini")
if err != nil {
fmt.Println("配置文件读取错误,请检查文件路径:", err)
}
//读取数据配置
DBUser := file.Section("database").Key("DbUser").String()
Password := file.Section("database").Key("DbPassWord").String()
Host := file.Section("database").Key("DbHost").String()
Port := file.Section("database").Key("DbPort").MustInt(3306)
Db := file.Section("database").Key("DbName").String()
connArgs := fmt.Sprintf("%s:%s@(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", DBUser, Password, Host, Port, Db)
//创建一个数据库的连接
db, err = gorm.Open("mysql", connArgs)
// defer db.Close()
if err != nil {
panic(err)
}
db.SingularTable(true) //去掉数据库自动迁移数据名加的s
db.AutoMigrate(&UrlList{}, &UrlType{}) //自动迁移
}
func DBClose() {
if err := db.Close(); err != nil {
log.Println("数据库关闭失败:" + err.Error())
}
}
type UrlType struct {
ID uint `gorm:"primary_key"`
Name string
UrlLists []UrlList `gorm:"FOREIGNKEY:TypeID;ASSOCIATION_FOREIGNKEY:ID"`
}
type UrlList struct {
ID uint `gorm:"primary_key"`
TypeID uint // 默认外键, 用户Id
Name string
URL string
}
func GetList() (data interface{}, err error) {
var list []UrlType
db.Debug().Preload("UrlLists").Find(&list)
return list, nil
}
复制代码
route
路由定义,增加一些服务器错误路由,路由404错误,并且把中间件放在这里。
package router
import (
"log"
"main/controller"
"main/global"
"main/middleware"
"net/http"
"runtime/debug"
"github.com/gin-gonic/gin"
)
//Router 路由方法
func Router() *gin.Engine {
router := gin.Default()
//处理异常
router.NoRoute(HandleNotFound)
router.NoMethod(HandleNotFound)
router.Use(Recover)
router.Use(middleware.Cors())
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, 1)
return
})
router.GET("/api", controller.Api)
return router
}
//HandleNotFound 404
func HandleNotFound(c *gin.Context) {
global.NewResult(c).Error(404, "资源未找到", nil)
return
}
//Recover 500
func Recover(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
//打印错误堆栈信息
log.Printf("panic: %v\n", r)
debug.PrintStack()
global.NewResult(c).Error(500, "服务器内部错误", nil)
}
}()
//继续后续接口调用
c.Next()
}
复制代码
mian
最后看一下main文件简话的内容,这里引入了model,在框架启动开始和结束分别打开和结束数据库的连接。还有引入了路由了,这里看不到路由相关逻辑了,很简洁~
package main
import (
"fmt"
"main/model"
"main/router"
"github.com/gin-gonic/gin"
_ "github.com/jinzhu/gorm/dialects/mysql"
"gopkg.in/ini.v1"
)
var HttpPort string
var AppMode string
type config struct {
App string
}
func init() {
//配置文件路径
file, err := ini.Load("config.ini")
if err != nil {
fmt.Println("配置文件读取错误,请检查文件路径:", err)
}
//读取项目运行
HttpPort = file.Section("server").Key("HttpPort").String()
AppMode = file.Section("server").Key("AppMode").String()
}
func main() {
model.DbConnect()
defer model.DBClose()
r := router.Router()
gin.SetMode(AppMode)
r.Run(HttpPort)
}
复制代码
总结
最后看一下项目目录结构:
整体就比较完善了,后面再增加路由,查询方法就在各自文件添加就可以了,很有条理。