使用 Gin 构建示例项目。
项目结构
基础必备模块
- 入口启动模块
- 项目启动类( main 函数/启动入口 )
- 配置加载、模块初始化
- 服务注册、端口监听
- 配置模块
- 环境配置(开发/测试/生产)
- 数据库、Redis、MQ、第三方服务密钥配置
- 统一配置中心(大型项目)
- 接口控制层( Controller/API ):作为前端请求,参数校验,返回结果
- RESTful API 接口
- 请求参数校验
- 统一返回格式
- 跨域、限流、鉴权前置处理
- 业务逻辑层( Service ):所有核心业务规则都写在这里
- 业务流程处理
- 事务控制
- 调用数据、第三方接口
- 不直接处理请求,也不直接操作数据库
- 数据库(DAO/Repository/Mapper):和数据库打交道
- CRUD 操作
- 数据查询、联表、分页
- 不写业务逻辑、,只写数据读写
- 实体模型层(Model/Entity/POJO)
- 数据库表对应实体(DO)
- 请求参数对象(DTO)
- 返回数据对象(VO)
- 数据传输转换
通用支撑模块
- 统一工具类模块
- 日期工具
- 加密解密
- JSON 工具
- 文件处理
- 字符串、集合工具
- 异常处理模块
- 全局异常捕获
- 自定义业务异常
- 统一错误码
- 异常日志记录
- 通用返回封装
- 统一响应格式
code/msg/data - 成功/失败工具方法
- 统一响应格式
高级功能模块
- 权限安全模块
- 用户登陆、登出
- Token/JWT/Session
- 角色权限(RBAC)
- 接口鉴权、防刷、黑名单
- 缓存模块(Redis)
- 热点数据缓存
- 分布式锁
- 限流
- 会话储存
- 消息列队模块(MQ)
- 异步解耦
- 流量削峰
- 日志、通知、订单延迟处理
- 文件处理模块
- 本地/OSS/MinIO 文件上传下载
- 图片处理、格式校验
- 定时任务模块
- 定时统计
- 定时清理
- 定时同步数据
- 第三方接口集成模块
- 短信、邮件
- 支付、推送
- 外部系统 API 调用
部署和运维模块
- 数据库脚本模块
- SQL 建表数据
- 数据初始化脚本
- 版本更新脚本
- 测试模块
- 单元测试
- 接口测试
- 压力测试
- 文档模块
- API 文档(Swagger/Knife4j)
- 项目说明文档
- 部署文件
- 构建部署配置
- Dockerfile
- 打包脚本
- CI/CD 配置
初始化
初始化项目:
go mod init gin-demo
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u github.com/golang-jwt/jwt/v5
go get -u github.com/joho/godotenv
目录结构
- "cmd/" 应用入口,存放 main.go
- "main.go" 初始化配置、组装各层依赖、启动 HTTP 服务器(不应包含任何逻辑代码)
- "internal/" 私有应用代码,进制外部项目导入
- "app/" 应用核心,负责组装依赖、启动服务
- "wire.go" (可选)依赖注入工具 write 的代码
- "bootstrap.go" 服务启动引导逻辑
- "config/" 配置加载与解析
- "config.go"
- "handler/" HTTP 处理器层(Controller),负责处理 HTTP 请求。它的任务很纯粹:解析请求参数、调用
service层处理业务、格式化并返回响应。它不包含任何复杂的业务逻辑- "user/" (项目大时可分文件组织)
- "service/" 业务逻辑层,承载整个应用的核心业务规则,它协调一个或多个
repository来完成一个完整的业务操作- "user/"
- "repository/" 数据访问层(DAO),负责与数据库、缓存等数据源进行交互。它将数据的增删改查细节封装起来,对
service层提供一个干净的接口。只负责和数据库说话,不包含任何业务逻辑- "user/"
- "model/" 数据模型层,定义数据的结构,例如与数据库表对应的实体( Entity )或数据传输对象( DTO ,返给前端的 JSON )
- "user/"
- "middleware/" 自定义中间件
- "jwt_auth.go"
- "app/" 应用核心,负责组装依赖、启动服务
- "pkg" 公共代码库,可被其他项目复用。存放与具体业务无关、可以被多个项目共享的工具库。例如,一个封装好的日志组件、统一的相应格式工具等
- "logger/"
- "response/"
- "api/" API 协议定义(如 OpenAPI/Swagger ),便于前后端协作和自动生成客户端代码
- "openapi.yaml"
- "configs" 外部配置文件(如 .yaml, .toml),通常配合
viper等库来加载,实现代码与配置的分离- "config.yaml"
- "scripts/" 各类脚本(部署、数据库迁移等)
- "test/" 集成测试、端到端测试
- "tmp" air (临时)工作目录
- ".air.toml" air 配置文件
- "go.mod"
- "go.sum"
- "README.md" 读我
包
Go Zero
一款优秀的模版生成神奇,但是作为学习 Go/Gin 的我来说,这个不太需要
热重载 air
安装
# 使用全局安装。不 -u
go install github.com/air-verse/air@latest
# 项目根初始化
# 在项目的根生成一个 `.air.toml` 配置文件
air init
环境变量配置:
# mac 或 linux
export PATH="$PATH:$(go env GOPATH)/bin"
数据库 GORM
安装:
go get -u github.com/
配置读取 viper
安装:
go get github.com/spf13/viper
构建 configs/config.dev.yaml 、 config/config.prod.yaml 配置文件,并在 internal/config/config.go 中使用 viper 根据启动环境变量(使用 os.Getenv("App_ENV"))读取配置项
# 在 Linux 服务器上
export APP_ENV=prod
./main # 编译好的二进制文件
# 或者在 Docker/K8s 中
docker run -e APP_ENV=prod xxxx
如果是敏感信息(如数据库密码、JWT 密钥)通常通过环境变量直接注入,覆盖配置文件
// 在 InitConfig 中加入这一行
viper.AutomaticEnv() // 自动读取环境变量
viper.SetEnvPrefix("App") // 环境变量前缀
// 此时,如果在系统里设置了 export APP_DATABASE_DSN="..."
// viper.GetString("database.dsn") 将自动读取环境变量的值,而不是文件的值!