GO分层架构【2】使用GIN与GORM

现在大家都使用的的GIN和GORM开发架构是怎么样的?

目前在 Go 社区中,基于 Gin 和 GORM 的主流微服务开发架构,最推崇的是 "工程化分层"。它在你的基础上,通过引入 Logic/Service 层 和 Repository 层,彻底解决代码臃肿和难以测试的问题。

以下是目前最流行的标准架构拆解:

1. 核心分层架构图

数据流向遵循:请求 → Handler → Logic → Repository → Database。

复制代码
internal/
├── handler/       # (入口层) 负责 Gin 的参数绑定、简单校验、返回 JSON
├── logic/         # (业务层) 核心是大脑!组合业务步骤,不涉及具体 SQL
├── repository/    # (持久层) 只有这里出现 GORM,负责具体的增删改查
├── model/         # (模型层) 定义 GORM 结构体(Table Schema)
└── middleware/    # (中间件) 权限校验、日志记录

2. 各层代码示例(以"用户充值"为例)

第一层:model (定义表结构)

复制代码
package model

type User struct {
    ID      uint   `gorm:"primaryKey"`
    Balance int64  `gorm:"column:balance"` // 余额
}

第二层:repository (数据操作 - 只有它认识 GORM)

复制代码
package repository

import "your-project/internal/model"
import "gorm.io/gorm"

type UserRepo struct {
    db *gorm.DB
}

func (r *UserRepo) UpdateBalance(id uint, amount int64) error {
    // 纯粹的数据库操作
    return r.db.Model(&model.User{}).Where("id = ?", id).
        Update("balance", gorm.Expr("balance + ?", amount)).Error
}

第三层:logic (业务核心 - 这里处理复杂逻辑)

复制代码
package logic

import "your-project/internal/repository"

type UserLogic struct {
    repo *repository.UserRepo
}

func (l *UserLogic) Recharge(userId uint, money int64) error {
    // 1. 这里处理业务规则:比如充值不能小于 0
    if money <= 0 { return errors.New("金额错误") }
    
    // 2. 调用数据层
    return l.repo.UpdateBalance(userId, money)
}

第四层:handler (Gin 入口 - 只管翻译)

复制代码
package handler

import "your-project/pkg/res" // 你之前定义的统一返回

func RechargeHandler(c *gin.Context) {
    var req struct { UserId uint; Amount int64 }
    c.ShouldBindJSON(&req) // 参数解析

    // 调用 Logic 层
    err := logic.NewUserLogic().Recharge(req.UserId, req.Amount)

    if err != nil {
        c.JSON(200, res.Error(500, err.Error()))
        return
    }
    c.JSON(200, res.Success(nil)) // 统一格式返回
}

3. 为什么这是主流?

  1. GORM 不外溢:GORM 的代码只出现在 repositoryinfra。如果你哪天想换 sqlxent,只需要改底层,不需要动 logichandler
  2. Logic 层可复用:
    • API 调用:通过 handlerlogic
    • 定时任务:通过 cronlogic
    • 自检脚本:通过 test/clientlogic
  3. 并发安全与事务:主流做法是在 logic 层通过闭包或 Context 处理事务,确保业务的原子性。

4. 针对你现状的调整建议

  • infra 细化:你现在的 infra 可能只是初始化 DB 连接。建议在 infra 下建一个 repository 子目录,专门写 GORM 的查询。
  • 增加 logic 文件夹:把你 handler 里那些复杂的 if-else、计算、多步 SQL 写入全部挪到 logic 里。
  • 统一返回:继续使用你放在 pkg/res 下的结构体,这是非常地道的做法。

避坑指南:在 GORM 开发中,千万不要把 *gin.Context 传进 logic 层或数据库层,这会导致你的业务逻辑和 HTTP 框架死死锁定。

相关推荐
用户34232323763171 天前
开源!Go+Wails+Vue3 手搓一个 PLC 实时监控桌面工具
go
止语Lab1 天前
为什么你的 Go TCP server P99 延迟这么高
go
Andy Dennis1 天前
nsq学习记录
消息队列·go·nsq
韦胖漫谈IT1 天前
选语言不是站队,是选适合问题的工具
java·python·ai·rust·go·技术落地
喵个咪2 天前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
夜悊2 天前
Go网络编程的学习代码示例:客户端/服务端(C/S)模型
go
审判长烧鸡2 天前
【AI问答】GO代码循环返值
go
捧 花2 天前
Eino框架记忆功能实现指南
go·agent·eino
Java陈序员2 天前
主流数据库通吃!一款开源实用的数据库备份管理工具!
react.js·postgresql·go
云浪2 天前
搞懂 Go WaitGroup:一篇文章彻底理解并发等待机制
后端·go