Gin项目配置

一、项目创建

  • api:请求方法
  • config:项目配置
  • core:核心库
  • result:结果返回集
  • global:全局共享数据
  • middleware:中间件
  • mode:模型
  • router:路由
  • utils:工具类
  • constant:常量化
  • config.yaml:配置文件
  • main.go:启动程序

二、系统配置

2.1 依赖下载
go get gopkg.in/yaml.v2
2.2 在config.yaml配置数据信息
# 系统配置
system:
  host: "0.0.0.0"
  port: 5001
  env: debug
  # env: releose
2.3 在config文件夹下新建config.go文件
// 读取配置文件
// @author Percy

package config

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
)

// config 总配置文件
type config struct {
    System system `yaml:"system"`
}

// 系统配置
type system struct {
    Host string `yaml:"host"`
    Port int    `yaml:"port"`
    Env  string `yaml:"env"`
}

var Config *config

// init 初始化配置
func init() {
    yamlFile, err := os.ReadFile("./config.yaml")
    if err != nil {
        return
    }
    yaml.Unmarshal(yamlFile, &Config)
}

三、日志配置

3.1 下载依赖
go get github.com/sirupsen/logrus
 3.2 在config.yaml配置数据信息
# logger 日志
logger:
  level: info
  prefix: "[gin-admin-api]"
  director: logger
  show_line: true
  log_in_console: true
3.3 在config.go新增日志配置
// 读取配置文件
// @author Percy

package config

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
)

// config 总配置文件
type config struct {
    System system `yaml:"system"`
    Logger logger `yaml:"logger"`
}

// 系统配置
type system struct {
    Host string `yaml:"host"`
    Port int    `yaml:"port"`
    Env  string `yaml:"env"`
}

// logger 日志
type logger struct {
    Level        string `yaml:"level"`
    Prefix       string `yaml:"perfix"`
    Director     string `yaml:"director"`
    ShowLine     bool   `yaml:"show_line"`
    LogInConsole bool   `yaml:"log_in_console"`
}

var Config *config

// init 初始化配置
func init() {
    yamlFile, err := ioutil.ReadFile("./config.yaml")
    if err != nil {
        return
    }
    yaml.Unmarshal(yamlFile, &Config)
}
 3.4 在core文件夹下新建logger.go文件,对日志信息进行自定义
// 日志配置
// @author Percy

package core

import (
	"bytes"
	"fmt"
	"github.com/sirupsen/logrus"
	"os"
	"path"
	"server/config"
)

// 颜色
const (
	red    = 31
	yellow = 33
	blue   = 36
	gray   = 37
)

type LogFormatter struct{}

// Format 实现Formatter(entry *logurs.Entry)([]byte, error)接口
func (t *LogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	// 根据不同的level去展示颜色
	var levelColor int
	switch entry.Level {
	case logrus.DebugLevel, logrus.TraceLevel:
		levelColor = gray
	case logrus.WarnLevel:
		levelColor = yellow
	case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
		levelColor = red
	default:
		levelColor = blue
	}

	var b *bytes.Buffer
	if entry.Buffer != nil {
		b = entry.Buffer
	} else {
		b = &bytes.Buffer{}
	}
	log := config.Config.Logger
	// 自定义日期格式
	timestamp := entry.Time.Format("2006-01-02 15:04:05")
	if entry.HasCaller() {
		//自定义文件路径
		funcVal := entry.Caller.Function
		fileVal := fmt.Sprintf("%s:%d", path.Base(entry.Caller.File), entry.Caller.Line)
		// 自定义输出格式
		fmt.Fprintf(b, "%s[%s] \x1b[%dm[%s]\x1b[0m] %s %s %s\n", log.Prefix, timestamp, levelColor, entry.Level, funcVal, fileVal, entry.Message)
	} else {
		fmt.Fprintf(b, "%s[%s] \x1b[%dm[%s]\x1b[0m] %s %s\n", log.Prefix, timestamp, levelColor, entry.Level, entry.Message)

	}
	return b.Bytes(), nil
}

// InitLogger 初始化
func InitLogger() *logrus.Logger {
	mLog := logrus.New()                                // 新建一个实例
	mLog.SetOutput(os.Stdout)                           // 设置输出类型
	mLog.SetReportCaller(config.Config.Logger.ShowLine) // 开启返回函数名和行号
	mLog.SetFormatter(&LogFormatter{})                  // 设置自己定义的Formatter
	level, err := logrus.ParseLevel(config.Config.Logger.Level)
	if err != nil {
		level = logrus.InfoLevel
	}

	mLog.SetLevel(level) // 设置最低的Level
	InitDefaultLogger()  // 不注释即启用全局log
	return mLog
}

// InitDefaultLogger 全局log
func InitDefaultLogger() {
	logrus.SetOutput(os.Stdout)                           // 设置输出类型
	logrus.SetReportCaller(config.Config.Logger.ShowLine) // 开启返回函数名和行号
	logrus.SetFormatter(&LogFormatter{})                  // 设置自己定义的Formatter
	level, err := logrus.ParseLevel(config.Config.Logger.Level)
	if err != nil {
		level = logrus.InfoLevel
	}
	logrus.SetLevel(level) // 设置最低的Level
}
3.5 在global文件夹下新建global.go文件
// 全局共享配置
// @author Percy

package global

var (
    Log *logrus.Logger
)
3.6 调用
// 初始化logger
global.Log = core.InitLogger()
global.Log.Warnln("go的日志 -> 警告(颜色黄)")
global.Log.Error("go的日志 -> 异常(颜色红)")
global.Log.Infof("go的日志 -> 正常(颜色蓝)")

四、mysql配置

4.1 下载依赖
// mysql依赖
go get -u gorm.io/driver/mysql 

// gorm依赖
go get -u gorm.io/gorm
 4.2 在config.yaml配置数据信息
# mysql 配置
mysql:
  host: 127.0.0.1
  port: 3306
  db: gin-blog # 数据库名称
  username: root
  password: root
  log_level: dev
  charset: utf8
  max_idle: 50
  max_open: 150
 4.3 在config.go新增日志配置

// config 总配置文件
type config struct {
    Mysql mysql `yaml:"mysql"`
}

// 数据库配置
type mysql struct {
    Host     string `yaml:"host"`
    Port     int    `yaml:"port"`
    Db       string `yaml:"db"`
    Username string `yaml:"username"`
    Password string `yaml:"password"`
    LogLevel string `yaml:"log_level"`
    Charset  string `yaml:"charset"`
    MaxIdle  int    `yaml:"max_idle"`
    MaxOpen  int    `yaml:"max_open"`

}
 4.4 调用
global.log.Infof("mysql配置:%s",config.Config.Mysql)
 4.5 在core文件夹下新建mysql.go文件
// mysql初始化配置
// @author Percy

package core

var Db *gorm.DB

func MysqlInit() err {
    var err error
    var dbConfig = config.Config.Mysql
    url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
        dbConfig.Username,
        dbConfig.Password,
        dbConfig.Host,
        dbConfig.Port,
        dbConfig.Db,
        dbConfig.Charset
    )
    Db, err = gorm.Open(mysql.Open(url), &gorm.Config{
        Logger: logger.Default.LogMode(logger.Info),
        DisableForeignKeyConstraintWhenMigrating: true,
    })

    if err != nil {
        return err
    }
    if Db.Error != nil {
        return err
    }
    sqlDb, err := Db.DB()
    sqlDb.SetMaxIdleConns(dbConfig.MaxIdle)
    sqlDb.setMaxOpenConns(dbConfig.MaxOpen)
    global.Log.Infof("[mysql]连接成功")
    return nil
}
4.6 在main.go文件初始化数据库
// 初始化mysql
core.MysqlInit()

五、redis配置

5.1下载依赖
go get github.com/go-redis/redis/v8
 5.2 在config.yaml配置数据信息
# redis配置
redis:
  address: 127.0.0.1:6379
  password: 123456
  db: 0
 5.3 在config.go新增日志配置

// config 总配置文件
type config struct {
    Redis redis`yaml:"redis"`
}

// 数据库配置
type redis struct {
    Address  string `yaml:"address"`
    Password string `yaml:"password"`
    Db       string `yaml:"db"`
}
 5.4 在global.go文件添加上下文
var (
    Log *logger.Logger
    // 上下文
    Ctx = context.Background()
)
 5.5 在core文件夹下新建redis.go文件
// redis初始化配置
// @author Percy

package core

var RedisDb *redis.Client

func RedisInit() err {
    RedisDb = redis.NewClient(&redis.Options{
        Addr: config.Config.Redis.Address,
        Password: config.Config.Redis.Password,
        DB: config.Config.Redis.Db
    })
    _, err := RedisDb.Ping(global.Ctx).Result()
    if err != nil {
        return err
    }
    global.Log.Infof("[redis]连接成功")
    return nil
}
 5.6 在main.go文件初始化redis
// 初始化redis
core.RedisInit()

六、初始化路由

6.1 在router文件夹下新建router.go文件,并编写初始化函数
func InitRouter() *gin.Engine {
    // 设置启动模式
    gin.SetMode(config.Config.System.Env)
    router := gin.New()
    
    // 跌机时恢复
    router.Use(gin.Recovery())
    return router
}

func register(router *gin.Engine) {
    // todo 后续接口url
}
6.2 在main.go调用
// 初始化路由
router := router.InitRouter()
address := fmt.Sprintf("%s:%d",config.Config.System.Host, config.Config.System.Port)
global.Log.Infof("系统启动成功,运行在:%s",address)
router.Run(address)

七、通用结构返回

7.1 定义状态码和对应的错误信息
// 状态码和状态信息定义
// @author Percy

package result

// Codes 定义状态
type Codes struct {
	Message               map[uint]string
	Success               uint
	Failed                uint
}

// ApiCode 状态码
var ApiCode = &Codes{
	Success:               200,
	Failed:                501,
}

// 状态信息初始化
func init() {
	ApiCode.Message = map[uint]string{
		ApiCode.Success:               "成功",
		ApiCode.Failed:                "失败",
	}
}

// GetMessage 供外部调用
func (c *Codes) GetMessage(code uint) string {
	messge, ok := c.Message[code]
	if !ok {
		return ""
	}
	return messge
}
7.2 结构体返回
// 结构数据定义
// @author Percy

package result

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// Result 结构体
type Result struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

// Success 成功
func Success(c *gin.Context, data interface{}) {
	if data == nil {
		data = gin.H{}
	}
	res := Result{}
	res.Code = int(ApiCode.Success)
	res.Message = ApiCode.GetMessage(ApiCode.Success)
	res.Data = data
	c.JSON(http.StatusOK, res)
}

// Failed 失败
func Failed(c *gin.Context, code int, message string) {
	res := Result{}
	res.Code = code
	res.Message = message
	res.Data = gin.H{}
	c.JSON(http.StatusOK, res)
}

八、接入swag

8.1 下载依赖
go get github.com/swaggo/files
go get github.com/swaggo/gim-swagger
8.2 swag接口注释方法
// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1->启用,2->禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
	PageNum, _ := strconv.Atoi(c.Query("pageNum"))
	PageSize, _ := strconv.Atoi(c.Query("pageSize"))
	RoleName := c.Query("roleName")
	Status := c.Query("status")
	BeginTime := c.Query("beginTime")
	EndTime := c.Query("endTime")
	if PageSize < 1 {
		PageSize = 10
	}
	if PageNum < 1 {
		PageNum = 1
	}
	var sysRole []model.SysRole
	var count int64
	curDb := Db.Table("sys_role")
	if RoleName != "" {
		curDb = curDb.Where("role_name = ?", RoleName)
	}
	if BeginTime != "" && EndTime != "" {
		curDb = curDb.Where("crete_time BETWEEN ? AND ?", BeginTime, EndTime)
	}
	if Status != "" {
		curDb = curDb.Where("status = ?", Status)
	}
	curDb.Count(&count).Limit(PageSize).Offset(PageNum - 1).Order("create_time DESC").Find(&sysRole)
	result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRole})
}
8.3 使用,swag init会自动创建一个docs文件夹存放文件
// 对swag初始化,每次添加swag接口注释都要重新初始化一下
swag init



// 在main.go文件夹导入调用docs的init函数
import (
    ···
	_ "server/docs"
)

// 在浏览器输入 http://localhost:5001/swagger/index.html

### 创建或配置 Gin 项目的示例教程 #### 1. 安装依赖 在开始之前,需要确保已安装 Go 环境并设置好 GOPATH 和 GOBIN 路径。接着通过以下命令安装 Gin 框架: ```bash go get -u github.com/gin-gonic/gin ``` #### 2. 初始化项目结构 在一个空文件夹中初始化一个新的 Go 模块,并创建必要的目录结构。可以运行以下命令来初始化模块: ```bash go mod init myginproject ``` 这会生成 `go.mod` 文件,记录项目的依赖项。 #### 3. 编写基础代码 基于提供的示例[^3],可以在项目根目录下创建一个名为 `main.go` 的文件,并编写如下代码: ```go package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/", func(c *gin.Context) { c.String(200, "Hello, EuanSu") }) r.Run(":8080") // 默认监听端口为 8080 } ``` 这段代码定义了一个简单的 HTTP Server,当访问 `/` 路由时返回字符串 `"Hello, EuanSu"`。 #### 4. 配置环境变量 如果项目涉及敏感数据(如 API 密钥),建议使用 `.env` 文件管理这些变量。按照引用中的说明[^4],先创建一个 `.env.sample` 文件作为模板,再将其重命名为 `.env` 并填充实际值。随后在代码中引入 `godotenv` 库加载环境变量: ```go package main import ( "log" "os" "github.com/joho/godotenv" "github.com/gin-gonic/gin" ) func init() { err := godotenv.Load() if err != nil { log.Fatalf("无法加载 .env 文件:%v", err) } } func main() { auth0Domain := os.Getenv("AUTH0_DOMAIN") r := gin.Default() r.GET("/auth-domain", func(c *gin.Context) { c.JSON(200, gin.H{ "domain": auth0Domain, }) }) r.Run(":8080") } ``` 此部分展示了如何读取环境变量并将它嵌入到响应逻辑中。 #### 5. 使用热加载工具提升开发效率 为了提高开发体验,可利用第三方插件实现代码修改后的自动重启功能。推荐使用的工具有 `air` 或者 `fresh`。以下是 `air` 的基本用法[^1]: - 下载工具:`go install github.com/cosmtrek/air@latest` - 启动服务:`air` 这样无需手动停止和重新启动服务器即可看到更改效果。 #### 6. 参考官方示例仓库扩展功能 对于更复杂的场景需求,可以直接参考官方维护的示例代码库[^2]获取灵感和支持。该资源包含了众多实用案例,比如处理表单提交、上传文件以及集成数据库操作等。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值