Go语学习笔记 - 项目规范结构调整 | Web框架Gin(三)

     阅读:21

学习笔记,写到哪是哪。

接着上一篇的文章构建的项目:Go语学习笔记 - 配置文件使用、日志配置 | Web框架Gin(二)_剑客阿良_ALiang的博客-CSDN博客

已经把配置文件和日志都加上了,更加符合项目的使用。

但是还是想把项目结构向类似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函数里面的一些警告,慢慢来吧。