88 lines
2.9 KiB
Markdown
88 lines
2.9 KiB
Markdown
# 4.3 后端分层架构
|
||
|
||
:::tip 概述
|
||
后端按职责分为五层:契约(dto)、接口(handler)、业务(service)、数据(repository)、横切(middleware + hooks)。每层只做一件事,依赖单向向下。
|
||
:::
|
||
|
||
## 分层与依赖方向
|
||
|
||
```text
|
||
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 | 认证、租户、鉴权、日志、限流、信封 | 业务逻辑 |
|
||
|
||
## 单例与调用约定
|
||
|
||
```text
|
||
service:var Xxx *sXxx(init 注册,全进程单例,方法必须并发安全)
|
||
跨模块:同包直调 —— User.Page(...)、repository.NewDeptRepo()(无需 import)
|
||
仓储:无状态(仅持表名),NewXxxRepo() 按需构造、可并发使用
|
||
```
|
||
|
||
## 事务边界
|
||
|
||
事务是 service 的职责:
|
||
|
||
```go
|
||
db.WithTrans(ctx, func(ctx context.Context) error {
|
||
// 回调内使用入参 ctx——它携带事务连接
|
||
// 内部所有 repository.Ctx(ctx) 自动加入事务
|
||
// 返回非 nil 错误整体回滚
|
||
})
|
||
```
|
||
|
||
repository 无感知事务——它永远从 ctx 取连接,这是 ctx 贯穿设计的直接收益。
|
||
|
||
## 错误传播
|
||
|
||
```text
|
||
repository 返回 gorm 错误
|
||
↓
|
||
service 映射为业务错误(consts 哨兵 / apperr.Newf)或原样上抛
|
||
↓
|
||
handler 不接触,透传
|
||
↓
|
||
response 中间件统一映射为信封(apperr 按码输出,其余通用失败)
|
||
```
|
||
|
||
## 横切的两个执行点
|
||
|
||
| 执行点 | 时机 | 承担什么 |
|
||
|---|---|---|
|
||
| 中间件链 | HTTP 请求级 | 身份、租户、权限、日志、限流、信封 |
|
||
| GORM 全局钩子 | SQL 语句级 | 审计盖章、物理删除拦截 |
|
||
| repository Scope | SQL 构建前 | del_flag=0、租户过滤 |
|
||
|
||
同一个红线(软删/租户)在读写两侧分别由 Scope 与钩子执行,业务代码零参与。
|
||
|
||
## 模块文件规约回顾
|
||
|
||
一个模块固定四文件,写法见 [第 3 章 模块开发实战](/zh/guide/overview.html) 与 [12.4 模块开发规约](/zh/standards/module-code.html)。
|
||
|
||
## 下一步
|
||
|
||
→ [4.4 反射元数据驱动机制](/zh/architecture/bind-mechanism.html)
|