找回密码
 立即注册
首页 业界区 业界 一款Go语言Gin框架MVC脚手架,满足大部分场景 ...

一款Go语言Gin框架MVC脚手架,满足大部分场景

楞粳 昨天 22:50
一款Go语言Gin框架MVC脚手架,满足大部分场景

一个开箱即用的 MVC(Model-View-Controller)Go 脚手架,基于 Gin + RocketMQ,包含双数据库、统一响应、中间件与事件驱动示例。
这是什么

Gin-Framework-MVC 是一个面向 Go 语言的 MVC 工程脚手架,帮你快速搭建分层清晰的 Web 服务。项目内置用户与订单示例、RocketMQ 生产/消费、邮件通知示例、统一响应与中间件,适合作为团队工程模板,用于代码初始化,适用于大多数场景。
功能与 practice-projects/gin-ddd一致。有别于DDD架构,MVC架构更加简洁清晰,可以对比下DDD与MVC工程目录结构的差异,根据业务需要选择DDD或者MVC架构。
为什么要用 MVC?

很多人会在 Go 项目里直接把路由、业务、数据访问写在一起,小项目可以跑得很快,但模块一多就容易失控。MVC 的价值在于把职责拆开:Controller 负责 HTTP 交互,Service 承载业务规则,Repository 专注数据访问,Model 维护核心状态与行为。
总之,是否采用 MVC 和语言无关,重点在于业务复杂度与团队协作成本。对于中小型到中大型业务系统,MVC 能在“足够清晰”和“实现成本”之间取得很好平衡。
源码地址:https://github.com/microwind/design-patterns/tree/main/practice-projects/gin-mvc
项目目录:gin-mvc/
核心特点


  • 清晰 MVC 分层:Controller、Service、Repository、Model
  • Gin Web 框架:高性能 HTTP 服务
  • 事件驱动:业务事件 + RocketMQ 生产者/消费者
  • 双数据库支持:用户库 + 订单库可独立配置(默认 MySQL + PostgreSQL)
  • 统一响应格式:Response 封装,错误码按业务域划分
  • 全局中间件:请求 ID、日志、恢复、跨域
  • 可选邮件通知:订单创建事件驱动 SMTP 邮件发送
技术栈

技术版本说明Go1.21+语言版本Gin1.9+HTTP 框架RocketMQ5.3+事件消息队列MySQL8.0+用户库默认PostgreSQL14+订单库默认YAML-配置文件格式工程结构

工程结构图

flowchart LR    Client[客户端]    subgraph Web["Web 入口"]        Router[Gin Router]        Middleware[Middleware]    end    subgraph MVC["MVC 核心"]        Controller[Controller]        Service[Service]        Model[Model]        View[View JSON/Template ]    end    subgraph Repo["数据访问"]        Repository[Repository]        UserDB[(MySQL 用户库)]        OrderDB[(PostgreSQL 订单库)]    end    subgraph Event["事件与通知"]        Producer[RocketMQ Producer]        Topic[(RocketMQ Topic)]        Consumer[RocketMQ Consumer]        Handler[Event Handler]        Mail[SMTP Mail]    end    Client --> Router    Router --> Middleware    Middleware --> Controller    Controller --> Service    Service --> Model    Service --> Repository    Repository --> UserDB    Repository --> OrderDB    Controller --> View    View --> Client    Service -.发布事件.-> Producer    Producer --> Topic    Topic --> Consumer    Consumer --> Handler    Handler --> Mail工程结构列表
  1. gin-mvc/
  2. ├── cmd/main.go                                  # 启动入口,装配各层并启动 HTTP + MQ
  3. ├── config/config.yaml                            # 应用配置
  4. ├── docs/
  5. │   ├── init_user_mysql.sql                       # MySQL 用户库初始化脚本
  6. │   └── init_order_postgres.sql                   # PostgreSQL 订单库初始化脚本
  7. ├── internal/
  8. │   ├── controllers/                              # Controller 层(HTTP 处理)
  9. │   │   ├── home/home_controller.go
  10. │   │   ├── order/order_controller.go
  11. │   │   └── user/user_controller.go
  12. │   ├── services/                                 # Service 层(业务编排)
  13. │   │   ├── order/order_service.go                # 订单服务(状态流转 + 发布事件)
  14. │   │   ├── user/user_service.go                  # 用户服务
  15. │   │   ├── event/order_handler.go                # 事件消费处理
  16. │   │   └── notification/mail_service.go          # 邮件服务接口
  17. │   ├── repository/                               # Repository 层(数据访问与外部依赖)
  18. │   │   ├── db/                                   # DB 连接与方言占位符
  19. │   │   ├── order/
  20. │   │   │   ├── order_repository.go
  21. │   │   │   └── order_sql_repository.go
  22. │   │   ├── user/
  23. │   │   │   ├── user_repository.go
  24. │   │   │   └── user_sql_repository.go
  25. │   │   ├── mq/                                   # RocketMQ 实现
  26. │   │   │   ├── rocketmq_producer.go
  27. │   │   │   └── rocketmq_consumer.go
  28. │   │   └── mail/smtp_mail_repository.go          # SMTP 邮件实现
  29. │   ├── models/                                   # Model 层(核心模型与事件)
  30. │   │   ├── order/order.go
  31. │   │   ├── user/user.go
  32. │   │   └── event/
  33. │   │       ├── event.go
  34. │   │       ├── order_event.go
  35. │   │       └── user_event.go
  36. │   ├── middleware/                               # Gin 中间件
  37. │   │   ├── request_id.go
  38. │   │   ├── logging.go
  39. │   │   ├── recovery.go
  40. │   │   ├── cors.go
  41. │   │   └── context.go
  42. │   └── config/config.go                          # 配置加载与校验
  43. ├── pkg/
  44. │   ├── logger/logger.go                          # 日志工具
  45. │   └── response/response.go                      # 统一响应
  46. └── web/templates/order.tmpl                      # 示例页面模板
复制代码
各层职责说明

层级位置职责关键原则Model 层internal/models/核心业务对象、状态机与事件模型聚焦业务语义,不依赖 HTTP/DB 细节Service 层internal/services/编排业务流程、状态流转、事件发布业务规则集中,避免散落到 ControllerRepository 层internal/repository/DB 访问、MQ/SMTP 等外部系统集成只做 IO 与持久化,不承载业务规则Controller 层internal/controllers/HTTP 请求解析、参数校验、响应输出轻量薄层,不直接操作数据库快速开始

1. 环境准备


  • Go 1.21+
  • MySQL 8.0+ 与 PostgreSQL 14+(或自行选择其一)
  • RocketMQ 5.3+(可选)
  • SMTP 邮箱(可选,推荐 QQ 邮箱)
2. 初始化数据库

默认配置使用双数据库:

  • 用户库:MySQL(默认库名 gin_mvc_user)
  • 订单库:PostgreSQL(默认库名 gin_mvc_order)
执行初始化脚本:
  1. mysql -u root -p < docs/init_user_mysql.sql
  2. psql -U postgres -f docs/init_order_postgres.sql
复制代码
数据库适配注意:

  • 当前仓储已同时支持 MySQL 与 PostgreSQL 占位符
  • 切换驱动时,确保 config/config.yaml 的 database.user.driver 与 database.order.driver 正确
3. 配置应用

编辑 config/config.yaml,至少配置数据库与 RocketMQ:
  1. server:
  2.   host: "0.0.0.0"
  3.   port: 8080
  4.   mode: "debug"
  5. database:
  6.   user:
  7.     driver: "mysql"
  8.     host: "localhost"
  9.     port: 3306
  10.     username: "root"
  11.     password: "your_password"
  12.     database: "gin_mvc_user"
  13.   order:
  14.     driver: "postgres"
  15.     host: "localhost"
  16.     port: 5432
  17.     username: "postgres"
  18.     password: "your_password"
  19.     database: "gin_mvc_order"
  20. rocketmq:
  21.   enabled: true
  22.   nameserver: "localhost:9876"
  23.   group_name: "gin-mvc-group"
  24.   instance_name: "gin-mvc-instance"
  25.   topics:
  26.     order_event: "order-event-topic"
复制代码
说明:

  • rocketmq.enabled: true 才会初始化生产者与消费者
  • rocketmq.topics.order_event 不能为空,否则配置校验会失败
  • 若暂不使用 MQ,可设置 rocketmq.enabled: false
最小可运行配置(本地联调推荐):

  • database.user 和 database.order 配置正确可连通
  • rocketmq.enabled: false(如果暂不使用消息)
  • mail.enabled: false(如果暂不发邮件)
4. 启动 RocketMQ(可选)
  1. sh bin/mqnamesrv
  2. sh bin/mqbroker -n localhost:9876
复制代码
5. 启动应用
  1. go mod tidy
  2. go run cmd/main.go
复制代码
6. 验证接口
  1. curl http://localhost:8080/health
  2. curl http://localhost:8080/api/users
  3. curl http://localhost:8080/api/orders
复制代码
API 一览

用户接口


  • POST /api/users
  • GET /api/users
  • GET /api/users/:id
  • PUT /api/users/:id/email
  • PUT /api/users/:id/phone
  • DELETE /api/users/:id
  • GET /api/users/:id/orders
示例:
  1. curl -X POST http://localhost:8080/api/users \
  2.   -H "Content-Type: application/json" \
  3.   -d '{"name":"张三","email":"zhangsan@example.com","phone":"13800138000"}'
复制代码
订单接口


  • POST /api/orders
  • GET /api/orders
  • GET /api/orders/:id
  • PUT /api/orders/:id/pay
  • PUT /api/orders/:id/ship
  • PUT /api/orders/:id/deliver
  • PUT /api/orders/:id/cancel
  • PUT /api/orders/:id/refund
示例:
  1. curl -X POST http://localhost:8080/api/orders \
  2.   -H "Content-Type: application/json" \
  3.   -d '{"user_id":1,"total_amount":99.99}'
复制代码
配置说明

config/config.yaml 主要分区:

  • server:主机、端口、Gin 模式、超时
  • database.user:用户库连接
  • database.order:订单库连接
  • log:日志级别与输出格式(text/json)
  • rocketmq:开关、nameserver、group、topic
  • mail:SMTP 开关与账号配置
如何基于脚手架开发新功能

示例:新增“商品管理”模块
步骤 1:新增模型 internal/models/product/product.go
  1. package product
  2. import "time"
  3. type Product struct {
  4.         ID        int64
  5.         Name      string
  6.         Price     float64
  7.         Stock     int
  8.         CreatedAt time.Time
  9.         UpdatedAt time.Time
  10. }
复制代码
步骤 2:新增仓储接口 internal/repository/product/product_repository.go
  1. package product
  2. import (
  3.         "context"
  4.         "gin-mvc/internal/models/product"
  5. )
  6. type Repository interface {
  7.         Create(ctx context.Context, p *product.Product) error
  8.         Update(ctx context.Context, p *product.Product) error
  9.         FindByID(ctx context.Context, id int64) (*product.Product, error)
  10.         FindAll(ctx context.Context) ([]*product.Product, error)
  11. }
复制代码
步骤 3:新增仓储实现 internal/repository/product/product_sql_repository.go
  1. package product
  2. import (
  3.         "context"
  4.         "database/sql"
  5.         "gin-mvc/internal/models/product"
  6. )
  7. type SQLRepository struct {
  8.         db *sql.DB
  9. }
  10. func NewSQLRepository(db *sql.DB) *SQLRepository {
  11.         return &SQLRepository{db: db}
  12. }
  13. func (r *SQLRepository) Create(ctx context.Context, p *product.Product) error {
  14.         _, err := r.db.ExecContext(ctx,
  15.                 `INSERT INTO products (name, price, stock, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`,
  16.                 p.Name, p.Price, p.Stock, p.CreatedAt, p.UpdatedAt,
  17.         )
  18.         return err
  19. }
复制代码
步骤 4:新增业务服务 internal/services/product/product_service.go
  1. package product
  2. import (
  3.         "context"
  4.         "time"
  5.         "gin-mvc/internal/models/product"
  6.         productRepo "gin-mvc/internal/repository/product"
  7. )
  8. type Service struct {
  9.         repo productRepo.Repository
  10. }
  11. func New(repo productRepo.Repository) *Service {
  12.         return &Service{repo: repo}
  13. }
  14. func (s *Service) Create(ctx context.Context, name string, price float64, stock int) error {
  15.         p := &product.Product{
  16.                 Name:      name,
  17.                 Price:     price,
  18.                 Stock:     stock,
  19.                 CreatedAt: time.Now(),
  20.                 UpdatedAt: time.Now(),
  21.         }
  22.         return s.repo.Create(ctx, p)
  23. }
复制代码
步骤 5:新增 Controller 和路由
将 Controller 放到 internal/controllers/product/,并在 cmd/main.go 中注册路由组 api.Group("/products")。
步骤 6:新增数据库表
  1. CREATE TABLE IF NOT EXISTS products (
  2.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  3.     name VARCHAR(100) NOT NULL,
  4.     price DECIMAL(10, 2) NOT NULL,
  5.     stock INT NOT NULL DEFAULT 0,
  6.     created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  7.     updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
  8. );
复制代码
事件驱动与 RocketMQ

事件类型

订单事件:

  • order.created
  • order.paid
  • order.shipped
  • order.delivered
  • order.cancelled
  • order.refunded
用户事件:

  • user.created
  • user.deleted
消息流转
  1. HTTP 请求 -> Controller -> Service -> Model/Repository
  2.             -> 发布 DomainEvent -> RocketMQ Producer
  3.             -> RocketMQ Broker -> Consumer
  4.             -> 事件处理 -> 发送邮件/触发后续流程
复制代码
订单创建场景(更具体):
  1. HTTP 请求
  2. -> OrderController
  3. -> OrderService(入库后发布事件)
  4. -> RocketMQ Producer
  5. -> RocketMQ Topic(order-event-topic)
  6. -> RocketMQ Consumer
  7. -> event handler
  8. -> SMTP MailService(order.created 时发送确认邮件)
复制代码
事件发布与消费关键点


  • 订单创建、支付、取消流程会尝试发布订单事件(发布失败不会中断主业务)
  • 消费端按 Tag 前缀解析消息:order.* 映射 OrderEvent,user.* 映射 UserEvent
  • 订单邮件通知仅在 order.created 且启用邮件时触发
邮件发送配置(QQ 邮箱)

在 config/config.yaml 中开启邮件配置:
  1. mail:
  2.   enabled: true
  3.   host: "smtp.qq.com"
  4.   port: 465
  5.   username: "your@qq.com"
  6.   password: "你的SMTP授权码"
  7.   from_email: "your@qq.com"
  8.   from_name: "订单系统"
复制代码
注意事项:

  • 必须使用 SMTP 授权码,不是 QQ 登录密码
  • 端口 465 使用 TLS,端口 587 使用 STARTTLS
  • 收件人取自用户表中的 email 字段
常见问题排查


  • 开启了 RocketMQ 但没有消息发布

    • 检查 rocketmq.enabled、NameServer/Broker 连接、topics.order_event 配置

  • 订单事件已消费但邮件未发送

    • 检查 mail.enabled、SMTP 授权码、用户邮箱字段是否正确

  • 消费者没有收到消息

    • 检查 Topic 与 Tag 是否匹配、Consumer Group 是否正常

  • 数据库报占位符或驱动错误

    • 检查 database.*.driver 与目标数据库是否匹配

开发规范

命名建议:

  • 模型:名词,如 Order、User
  • 服务:Service 或 XxxService
  • 仓储接口:Repository
  • 仓储实现:SQLRepository
  • 控制器:Controller 或 XxxController
分层原则:

  • Controller 只处理 HTTP 参数与响应
  • Service 负责业务规则、流程编排与事件发布
  • Repository 负责数据访问与外部依赖调用
  • Model 负责领域状态和对象行为
对比 DDD 版本

和 practice-projects/gin-ddd 对比:

  • 功能面保持一致:用户/订单/MQ/邮件/双库
  • 分层方式改为 MVC:更易理解和教学展示
  • 依赖注入在 cmd/main.go 统一装配,便于快速定位启动流程
常用命令
  1. go mod tidy
  2. go test ./...
复制代码
源码地址

MVC架构:
https://github.com/microwind/design-patterns/tree/main/practice-projects/gin-mvc
DDD架构:
https://github.com/microwind/design-patterns/tree/main/practice-projects/gin-ddd

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册