第 04 章 三层架构与请求流转
学习目标
学完本章,你应该能:
- 理解 fba 的「三层架构」是什么、为什么这样设计
- 搞清 API、Service、CRUD/DAO 三层各自的职责边界
- 理解一个请求从进来到返回的完整流转过程
一、什么是三层架构
fba 的核心设计是三层架构,把代码按职责拆成三层:
API 层(接口层) → 处理 HTTP 协议,收发请求
↓
Service 层(业务层) → 写业务逻辑,是核心
↓
CRUD/DAO 层(数据层)→ 读写数据库三层架构全景图
各层职责对比
| 层 | 别称 | 职责 | 不该做什么 |
|---|---|---|---|
| API 层 | 接口层 / controller | 接收请求、校验参数、调用 Service、返回响应 | 不写业务逻辑、不直接操作数据库 |
| Service 层 | 业务层 | 核心业务逻辑、编排多个数据操作、事务控制 | 不处理 HTTP 细节 |
| CRUD/DAO 层 | 数据层 / dao / mapper | 封装数据库增删改查 | 不写业务逻辑 |
对应到 fba 的目录
fba 用五个目录承载这三层(多了两个"定义数据"的目录):
| 目录 | 属于哪层 | 作用 |
|---|---|---|
api/ | API 层 | 定义路由接口 |
service/ | Service 层 | 业务逻辑 |
crud/ | CRUD 层 | 数据库操作 |
model/ | 数据定义 | 数据库表结构(ORM 模型) |
schema/ | 数据定义 | 请求/响应数据结构(校验模型) |
记住这个对照:model + schema 定义"数据长什么样",api + service + crud 定义"数据怎么流转"。
二、为什么不用 MVC 或 DDD?
这是官方 FAQ 里被问得最多的问题之一。简单理解:
- MVC(Model-View-Controller):偏 Web 全栈的经典模式,但后端和前端边界容易模糊。
- DDD(领域驱动设计):很强大,但学习成本高、结构重,适合超大型复杂业务。
- 三层架构:fba 的选择是——贴近后端工程实践、边界清晰、上手成本低,特别适合中后台、管理系统、内部平台这类项目。
三种架构的取舍对比
官方态度也很开放:如果三层架构不适合你的团队,可以在保留分层边界的前提下自行调整。
三、为什么分层这么重要
想象一个"不分层"的项目:接口函数里既写业务逻辑,又拼 SQL,还处理参数。结果就是——改一处逻辑要动整个函数,代码越写越乱,换人维护无从下手。
分层的好处:
- 职责清晰:每一层只做一件事,review 时不用纠结"这个代码放哪"
- 易维护:改业务逻辑只动 Service,改数据库操作只动 CRUD
- 易协作:多人并行开发,各写各的层,减少冲突
- 易测试:可以单独测试某一层
社区开发者的话印证了这点:
"最舒服的是边界感。API 处理协议,Service 写业务,CRUD/DAO 管数据访问,后面换人维护也能快速找到位置。"
四、请求流转详解
我们以一个"查询用户详情"的请求为例,走一遍完整流程:
时序图
文字版流程
1. 前端发起请求 GET /api/v1/user/1
2. 中间件处理:鉴权、日志、Trace ID
3. API 层:接收请求,Schema 校验参数,调用 Service
4. Service 层:执行业务逻辑,调用 CRUD
5. CRUD 层:执行数据库查询
6. 数据库返回数据
7. 数据逐层向上返回:CRUD → Service → API
8. API 层包装成统一响应格式,返回给前端五、一条铁律:业务逻辑不要下沉到 CRUD
官方特别强调的编码规范:
- 不要把业务逻辑下沉到 CRUD:CRUD 层只管"怎么查数据",不该管"该不该查"。
- 不要把查询细节散落到 API 层:API 层只管"接收请求、返回响应",不该拼查询条件。
正确姿势:
python
# ❌ 错误:在 API 层写查询逻辑
@router.get('/user/{id}')
async def get_user(id: int, db: CurrentSession):
user = await db.execute(select(User).where(User.id == id)) # 查询细节不该在这
# ✅ 正确:API 层只调用 Service
@router.get('/user/{id}')
async def get_user(id: int, user_service: UserService = Depends()):
return await user_service.get_user(id)职责边界示意
六、开发顺序(务必记住)
fba 推荐的开发顺序,也是 AI 辅助开发时的建议顺序:
先定义"数据长什么样",再定义"数据怎么流转",这是最顺手的开发顺序。
为什么要按这个顺序? 因为后面的层依赖前面的定义:CRUD 需要知道 Model 长什么样,Router 需要知道 Schema 长什么样,Service 需要调用 CRUD。从底层往上搭,不会出现"写到最后发现缺东西"的情况。
本章小结
关键要点回顾:
- 三层架构:API(协议)→ Service(业务)→ CRUD/DAO(数据访问)
- 五个目录:model + schema 定义数据,api + service + crud 处理流转
- 铁律:业务逻辑不进 CRUD,查询细节不进 API
- 开发顺序:model → schema → router → service → crud
- fba 选三层而非 MVC/DDD,是为了边界清晰 + 上手成本低
下一步: 从第 05 章开始,我们按这个顺序,逐个击破 model、schema、router、service、crud。
对应官方文档:
简介-三层架构(backend/summary/intro.html)、为什么选择我们-架构(backend/summary/why.html)