已经把配置文件和日志都加上了,更加符合项目的使用。
但是还是想把项目结构向类似java的mvc结构改造一下,这样后面的代码编写可以规范化,毕竟不可能所有的功能实现都放到main方法里面。
项目地址:github地址
路由层调整
在app/router目录内增加router.go和test_router.go两个文件。
其中router.go文件主要是提供初始化汇总的。
router.go代码如下:
package router import "github.com/gin-gonic/gin" func InitRouter(r *gin.Engine) { // 测试路由 TestRouter(r) }
test_router.go文件主要是配置test控制层的路由地址的。
test_router.go代码如下:
package router import ( "github.com/gin-gonic/gin" "learn-gin/app/controllers" ) func TestRouter(r *gin.Engine) { r.GET("/", controllers.TestCtrl.HelloWorld) r.GET("/test/:name", controllers.TestCtrl.TestParam) r.GET("/test1", controllers.TestCtrl.TestDefaultParam) r.POST("/testPost", controllers.TestCtrl.TestPost) r.POST("/testPost2", controllers.TestCtrl.TestPostBody) }
至于controllers相关内容下面会继续讲到。
控制层调整
在app/controllers目录下也增加两个文件controllers.go和test_controller.go。
其中controllers.go主要是将controller中的结构体进行对象声明,方便使用。
controllers.go的代码如下:
package controllers var ( TestCtrl = &TestController{} ) test_controller.go的代码如下: package controllers import ( "encoding/json" "github.com/gin-gonic/gin" "learn-gin/app/pojo/req" "learn-gin/app/services" "learn-gin/config/log" "net/http" ) type TestController struct { } func (t *TestController) HelloWorld(context *gin.Context) { log.Logger.Info("测试HelloWorld接口") context.String(http.StatusOK, "hello world") } func (t *TestController) TestParam(context *gin.Context) { name := context.Param("name") log.Logger.Info("测试TestParam接口") context.String(http.StatusOK, "check param %s", name) } func (t *TestController) TestDefaultParam(context *gin.Context) { name := context.DefaultQuery("name", "张三") gender := context.Query("gender") log.Logger.Info("测试TestDefaultParam接口") context.String(http.StatusOK, "他叫%s,性别:%s", name, gender) } func (t *TestController) TestPost(context *gin.Context) { name := context.PostForm("name") nick := context.DefaultPostForm("nick", "leo") log.Logger.Info("测试TestPost接口") context.JSON(http.StatusOK, gin.H{ "status": gin.H{ "code": http.StatusOK, "success": true, }, "name": name, "nick": nick, }) } func (t *TestController) TestPostBody(context *gin.Context) { var request req.TestPostRequest log.Logger.Info("测试TestPostBody接口") if err := context.ShouldBindJSON(&request); err != nil { log.Logger.Panic("参数异常") } if _, err := json.Marshal(request); err != nil { log.Logger.Panic("参数解析异常") } services.TestServ.PrintInfo(&request) context.JSON(http.StatusOK, gin.H{ "code": http.StatusOK, "data": request, }) }
这里就复杂了,用到了services目录以及pojo目录,下面会提到。总体上就是把之前在main方法中实现的接口功能,移到了这里。
服务层调整
在app/services目录下增加services.go和test_service.go两个文件,和控制层一样。
其中services.go文件主要是将service中的结构体进行对象声明,方便使用。
services.go代码如下:
package services var ( TestServ = &Test{} ) test_service.go代码如下: package services import ( "fmt" "learn-gin/app/pojo/req" ) type TestService interface { PrintInfo(req *req.TestPostRequest) } type Test struct { } func (t Test) PrintInfo(req *req.TestPostRequest) { fmt.Printf("测试数据,name=%s,age=%d\n", req.Name, req.Age) }
可以看出,使用了接口,结构体Test实现了PrintInfo方法,可以结合test_controller.go文件理解一下逻辑。
实体调整
在服务层可以看到我们使用到了一个实体,TestPostRequest。我们在app/pojo下创建了一个req目录,增加了test_request.go文件。
test_request.go代码如下:
package req
type TestPostRequest struct {
Name string `json:"name"`
Age int `json:"age"`
}
main方法调整
将main方法调整为如下:
package main import ( "github.com/gin-gonic/gin" "learn-gin/app/router" "learn-gin/config/log" "learn-gin/config/toml" ) func main() { log.InitLogger(toml.GetConfig().Log.Path, toml.GetConfig().Log.Level) log.Logger.Info("hahahah") log.Logger.Info("config", log.Any("config", toml.GetConfig())) r := gin.Default() router.InitRouter(r) r.Run(":8080") }
验证一下
项目改好了,我们测试一下接口,启动截图如下。
执行testPosts接口截图如下。
正确的情况下,我们看一下日志。
看一下参数异常情况下的日志。
OK没啥问题。
小结
后面的话,考虑继续调整,看到了目前main函数里面的一些警告,慢慢来吧。