• 学习gin-vue-admin之创建api和swagger


    go:generate

    //go:generate go env -w GO111MODULE=on
    //go:generate go env -w GOPROXY=https://goproxy.cn,direct
    //go:generate go mod tidy
    //go:generate go mod download

    Viper 读写配置文件
          v := viper.New()
    	v.SetConfigFile("config.yaml")
    	v.SetConfigType("yaml")
    	err := v.ReadInConfig()
    	if err != nil {
    		panic(fmt.Errorf("Fatal error config file: %s \n", err))
    	}
    	if err = v.Unmarshal(&global.GVA_CONFIG); err != nil {
    		fmt.Println(err)
    	}
    
    	cs := utils.StructToMap(global.GVA_CONFIG)
    	for k, v2 := range cs {
    		v.Set(k, v2)
    	}
    
    	v.WriteConfig()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    ZAP 保存日志

    global.GVA_LOG.Error(“获取失败!”, zap.Error(errors.New(“====”)))
    global.GVA_LOG.Info("server run success on ", zap.String(“address”, address))

    定时任务
        tm := timer.NewTimerTask()
    	_, err := tm.AddTaskByFunc("func", "@every 1s", mockFunc)
    	if err == nil {
    		tm.StartTask("func")
    		println("StartTask=func")
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    创建api

    model
    api 需要调用的api
    router 路由
    service 业务代码
    model->service->api->router-initRouter

    model
    
    type Userinfo struct {
    	Name string `uri:"name" form:"name" json:"name"`
    	Pwd  string `uri:"pwd" form:"pwd" json:"pwd"`
    }
    type UserinfoResponse struct {
    	Userinfo example.Userinfo `json:"userinfo"`
    	Token    string           `json:"token"`
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    步骤 1. 创建service
    1. example/exa_api.go
    type ExaApiService struct {
    }
    
    var ExaApiServiceApp = new(ExaApiService)
    
    func (exaApi *ExaApiService) Login(u example.Userinfo) string {
    	return fmt.Sprintf("Login2=name=%s password=%s", u.Name, u.Pwd)
    }
    
    func (exaApi *ExaApiService) GetUserInfo(u example.Userinfo) string {
    	return fmt.Sprintf("GetUserInfo2=name=%s password=%s", u.Name, u.Pwd)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. example/enter.go
    
    type ServiceGroup struct {
    	ExaApiService
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. enter.go
     type ServiceGroup struct {
    	ExaServiceGroup example.ServiceGroup
    }
    
    var ServiceGroupApp = new(ServiceGroup)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    步骤 2. 创建api
    1. example/enter.go
    
    type ApiGroup struct {
    	ExaApi
    }
    
    var (
    	exaService = service.ServiceGroupApp.ExaServiceGroup.ExaApiService
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. example/exa_api.go
    package example
    
    import (
    	"github.com/gin-gonic/gin"
    	"github.com/githubuityu/study_gin_admin/model/common/response"
    	"github.com/githubuityu/study_gin_admin/model/example"
    )
    
    type ExaApi struct {
    }
    
    // Login /*
    // http://127.0.0.1:8888/exaApi/login
    // application/x-www-form-urlencoded或者form-data
    func (e *ExaApi) Login(c *gin.Context) {
    	var userinfo example.Userinfo
    	err := c.ShouldBind(&userinfo)
    	if err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
    	response.OkWithMessage(exaService.Login(userinfo), c)
    }
    
    // http://127.0.0.1:8888/exaApi/getUserInfo?name=zhangsan&pwd=6666
    func (e *ExaApi) GetUserInfo(c *gin.Context) {
    	var userinfo example.Userinfo
    	err := c.ShouldBind(&userinfo)
    	if err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
    	response.OkWithMessage(exaService.GetUserInfo(userinfo), c)
    }
    
    // http://127.0.0.1:8888/exaApi/login
    //
    //	raw {
    //	   "name":"zhangsan",
    //	   "pwd":"23333"
    //	}
    func (e *ExaApi) LoginJson(c *gin.Context) {
    	var userinfo example.Userinfo
    	err := c.ShouldBindJSON(&userinfo)
    	if err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
    	response.OkWithMessage(exaService.Login(userinfo), c)
    }
    
    // http://127.0.0.1:8888/exaApi/getUserInfoPath/zhangsan/555
    func (e *ExaApi) GetUserInfoPath(c *gin.Context) {
    	var userinfo example.Userinfo
    	err := c.ShouldBindUri(&userinfo)
    	if err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
    	response.OkWithMessage(exaService.GetUserInfo(userinfo), c)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    1. enter.go
     type ApiGroup struct {
    	ExaApiGroup example.ApiGroup
     }
    
    var ApiGroupApp = new(ApiGroup)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    步骤 3. 创建router
    1. example/exa_api.go
    type ExaRouter struct {
    }
    
    func (e *ExaRouter) InitExaAPiRouter(Router *gin.RouterGroup) {
    	exaApiRouter := Router.Group("exaApi").Use(middleware.ExaMiddleware())
    	exaApiRouterWithoutRecord := Router.Group("exaApi")
    	exaApi := v1.ApiGroupApp.ExaApiGroup
    	{
    		exaApiRouter.POST("login", exaApi.Login)        
    		exaApiRouter.POST("loginJson", exaApi.LoginJson) 
    	}
    	{
    		exaApiRouterWithoutRecord.GET("getUserInfo", exaApi.GetUserInfo)                  
    		exaApiRouterWithoutRecord.GET("getUserInfoPath/:name/:pwd", exaApi.GetUserInfoPath) 
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. example/enter.go
    
    type RouterGroup struct {
    	ExaRouter
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. enter.go
    type RouterGroup struct {
    	Example example.RouterGroup
    }
    
    var RouterGroupApp = new(RouterGroup)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    初始化总路由
    
    func Routers() *gin.Engine {
    
    	// 设置为发布模式
    	if global.GVA_CONFIG.System.Env == "public" {
    		gin.SetMode(gin.ReleaseMode) //DebugMode ReleaseMode TestMode
    	}
    	Router := gin.New()
    	exaApiRouter := router.RouterGroupApp.Example
    
    	//PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
    
    	PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
    	{
    		// 健康监测
    		PublicGroup.GET("/health", func(c *gin.Context) {
    			c.JSON(http.StatusOK, "ok")
    		})
    	}
    	exaApiRouter.InitExaAPiRouter(PublicGroup)
    
    	global.GVA_LOG.Info("router register success")
    	return Router
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    启动
    
    package main
    
    import (
    	"fmt"
    	"github.com/githubuityu/study_gin_admin/core"
    	"github.com/githubuityu/study_gin_admin/global"
    	"github.com/githubuityu/study_gin_admin/initialize"
    	"go.uber.org/zap"
    	"time"
    )
    
    //go:generate go env -w GO111MODULE=on
    //go:generate go env -w GOPROXY=https://goproxy.cn,direct
    //go:generate go mod tidy
    //go:generate go mod download
    func main() {
    	global.GVA_VP = core.Viper() // 初始化Viper
    	initialize.OtherInit()
    	global.GVA_LOG = core.Zap() // 初始化zap日志库
    	zap.ReplaceGlobals(global.GVA_LOG)
    	global.GVA_DB = initialize.Gorm() // gorm连接数据库
    	initialize.Timer()
    	core.RunWindowsServer()
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    go-swagger

    参数类型 query、path、body、header,formData
    参数参数类型 string integer number boolean struct

    // Login
    // @Summary  用户登录
    // @Tags     ExaApi
    // @Produce   application/json
    // @Param name formData string false "名字"
    // @Param pwd formData string false "密码" 
    // @Success  200   {object}  response.Response{data=exaApiRes.UserinfoResponse,msg=string}  "返回包括用户信息,token,过期时间"
    // @Router   /exaApi/login [post]
    func (e *ExaApi) Login(c *gin.Context) {
    	var userinfo example.Userinfo
    	err := c.ShouldBind(&userinfo)
    	if err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
    	response.OkWithDetailed(exaApiRes.UserinfoResponse{
    		Userinfo: userinfo,
    		Token:    userinfo.Pwd,
    	}, "登录成功", c)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    路由配置
     docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
    Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    
    • 1
    • 2
    swag init
    test
    1. 创建一个a.go
    2. 创建一个测试文件a_test.go
    3. 创建一个方法方法名以Test开始,参数为(t *testing.T)
    //a.go
    package utils
    
    type TestA struct {
    	TestB
    }
    
    type TestB struct {
    }
    
    func (tb *TestB) GetInfo() string {
    	return "返回数据"
    }
    
    var ItyuTestA = new(TestA)
    
    
    package utils
    
    //a_test.go
    import "testing"
    
    func TestAaaa(t *testing.T) {
    	print(ItyuTestA.TestB.GetInfo())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    将嵌套结构定义为指针或对象利弊
    1. 将嵌套结构定义为指针:
      内存效率:使用指针可以提高内存效率,特别是当嵌套结构体很大时。指针只存储结构体的内存地址,而不是复制整个结构体的数据。
      可变性:如果你需要修改父结构中的嵌套结构的数据,使用指针允许你直接修改被引用的对象。
      避免nil值:如果嵌套结构可能有nil值,使用指针可以通过将指针设置为nil来表示值的缺失。

    2. 将嵌套结构定义为对象:
      简单性:直接使用对象可以简化代码,因为不需要处理指针解引用。它可以使代码更易于阅读和理解。
      避免与指针相关的问题:操作指针需要小心处理,以避免空指针异常和内存泄漏。使用对象可以帮助避免此类问题。
      不可变性:如果嵌套结构的数据在父结构中应该被视为不可变的,那么使用对象可以强制这种不可变性并防止无意的修改。

    3. 最终,对嵌套结构使用指针还是对象的选择取决于性能、可变性要求、内存使用和代码简单性等因素。考虑应用程序的具体需求,并根据这些需求做出决定。

    结构体嵌套

    结构体嵌套在编程中有多种作用和用途,以下是一些常见的用途:

    1. 组合数据:结构体嵌套允许将多个相关的数据字段组合在一起,形成更复杂的数据结构。通过嵌套其他结构体,可以在一个结构体中包含其他结构体的数据,从而形成逻辑上的组合关系。

    2. 嵌套层次:通过结构体嵌套,可以创建多层次的数据结构,形成树状或层次化的关系。这样可以更好地组织和管理数据,使其更具可读性和可维护性。

    3. 代码复用:结构体嵌套可以实现代码的复用。通过将一个结构体嵌套到另一个结构体中,可以共享嵌套结构体的字段和方法,避免重复定义和编写相同的代码。

    4. 组合功能:通过将一个结构体嵌套到另一个结构体中,可以将嵌套结构体的方法和行为组合到外部结构体中,形成更丰富的功能。外部结构体可以调用嵌套结构体的方法,实现更复杂的行为。

    5. 数据模型:结构体嵌套可以用于定义和表示复杂的数据模型。通过将多个相关的数据结构嵌套在一起,可以更好地表示现实世界的实体和关系。

    6. 总的来说,结构体嵌套提供了一种组合和组织数据的机制,可以使代码更具可读性、可维护性和复用性。它是构建复杂数据结构和实现代码组合的重要工具之一。

    学习资源

    gin-vue-admin

  • 相关阅读:
    源码分析:如何开发规则链
    buuctf-[GXYCTF2019]禁止套娃 git泄露,无参数rce
    fastadmin 后台列表数据多表查询筛选
    Linux 实现原理 — NUMA 多核架构中的多线程调度开销与性能优化
    危险边缘:揭示 Python 编程中易被忽视的四个安全陷阱
    LeetCode刷题笔记【33】:动态规划专题-5(最后一块石头的重量 II、目标和、一和零)
    C#使用自定义的泛型节点类 Node<T>实现二叉树类BinaryTree<T>及其方法
    yolov5原理
    什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解
    130家小程序,“火”的一塌糊涂
  • 原文地址:https://blog.csdn.net/yujunlong3919/article/details/133931758