Files
easygoadmin-wiki/EasyGoAdmin_Gin_AntdVue/zh/architecture/backend-layer.md
T
2026-10-25 17:24:27 +08:00

2.9 KiB
Raw Blame History

4.3 后端分层架构

:::tip 概述 后端按职责分为五层:契约(dto)、接口(handler)、业务(service)、数据(repository)、横切(middleware + hooks)。每层只做一件事,依赖单向向下。 :::

分层与依赖方向

middleware     横切处理(认证/租户/权限/日志/限流)
     │ 注入身份与上下文到 ctx
     ▼
handler        极薄委托(签名固定,反射注册)
     │
     ▼
service        业务规则(ModuleSpec 声明 + 手写逻辑 + 事务)
     │
     ▼
repository     数据访问(Ctx 入口注入软删/租户 Scope)
     │
     ▼
gorm + db      连接(多方言驱动注册表 + 全局钩子盖章)

dto 被所有层引用(契约);utility 被任意层引用(无业务语义)。

各层职责边界

层 做什么 不做什么
dto 请求/响应结构、binding/msg/form/json 标签、UnmarshalBody 业务判断
handler 委托调用、调用转换 参数解析、权限、规则
service 业务规则、事务、错误上抛、ModuleSpec 声明 HTTP 响应构造、裸 SQL 拼接
repository 条件查询、软删除、存在性判断 业务条件决策
middleware 认证、租户、鉴权、日志、限流、信封 业务逻辑

单例与调用约定

service:var Xxx *sXxx(init 注册,全进程单例,方法必须并发安全)
跨模块:同包直调 —— User.Page(...)、repository.NewDeptRepo()(无需 import)
仓储:无状态(仅持表名),NewXxxRepo() 按需构造、可并发使用

事务边界

事务是 service 的职责:

db.WithTrans(ctx, func(ctx context.Context) error {
    // 回调内使用入参 ctx——它携带事务连接
    // 内部所有 repository.Ctx(ctx) 自动加入事务
    // 返回非 nil 错误整体回滚
})

repository 无感知事务——它永远从 ctx 取连接,这是 ctx 贯穿设计的直接收益。

错误传播

repository 返回 gorm 错误
     ↓
service 映射为业务错误(consts 哨兵 / apperr.Newf)或原样上抛
     ↓
handler 不接触,透传
     ↓
response 中间件统一映射为信封(apperr 按码输出,其余通用失败)

横切的两个执行点

执行点 时机 承担什么
中间件链 HTTP 请求级 身份、租户、权限、日志、限流、信封
GORM 全局钩子 SQL 语句级 审计盖章、物理删除拦截
repository Scope SQL 构建前 del_flag=0、租户过滤

同一个红线(软删/租户)在读写两侧分别由 Scope 与钩子执行,业务代码零参与。

模块文件规约回顾

一个模块固定四文件,写法见 第 3 章 模块开发实战 与 12.4 模块开发规约。

下一步

→ 4.4 反射元数据驱动机制