Skip to content

第 04 章 三层架构与请求流转 ​

学习目标 ​

学完本章,你应该能:

  1. 理解 fba 的「三层架构」是什么、为什么这样设计
  2. 搞清 API、Service、CRUD/DAO 三层各自的职责边界
  3. 理解一个请求从进来到返回的完整流转过程

一、什么是三层架构 ​

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,还处理参数。结果就是——改一处逻辑要动整个函数,代码越写越乱,换人维护无从下手。

分层的好处:

  1. 职责清晰:每一层只做一件事,review 时不用纠结"这个代码放哪"
  2. 易维护:改业务逻辑只动 Service,改数据库操作只动 CRUD
  3. 易协作:多人并行开发,各写各的层,减少冲突
  4. 易测试:可以单独测试某一层

社区开发者的话印证了这点:

"最舒服的是边界感。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)