FastAPI 项目架构设计:按技术分层还是按业务模块?
很多刚开始学习FastAPI的同学都会遇到一个问题:
项目目录到底应该怎么组织?
是像Java Spring一样按照Controller、Service、Repository分层?
还是按照User、Order、Post这样的业务模块划分?
本文结合实际项目经验,聊聊这两种常见的项目组织方式,以及为什么越来越多的 FastAPI 项目都推荐采用按业务模块组织代码。
方案一:按技术层划分(Layer-based)
项目目录大致如下:
app/ ├── api/ │ ├── user.py │ ├── post.py │ └── comment.py │ ├── service/ │ ├── user_service.py │ ├── post_service.py │ └── comment_service.py │ ├── repository/ │ ├── user_repository.py │ ├── post_repository.py │ └── comment_repository.py │ ├── models/ ├── schemas/ └── utils/熟悉 Java 开发的同学应该对这种结构非常熟悉。
它来源于传统的三层架构(Controller → Service → Repository),也是很多 Spring Boot 项目的默认组织方式。因此,不少刚接触 FastAPI 的开发者也会沿用这种目录结构。
优点
- 结构简单,容易理解
- 新手上手快
- 小型项目开发效率较高
缺点
对于小项目来说,这种方式完全没有问题。
但随着业务不断增加,同一种类型的代码都会集中到一个目录中,一个目录下可能出现几十甚至上百个文件,维护成本也会逐渐提高。
例如修改一个用户功能,你可能需要在多个目录之间来回切换:
api/user.py service/user_service.py repository/user_repository.py models/user.py schemas/user.py如果项目继续扩展:
user role permission organization department tenant那么目录可能会变成:
service/ ├── user_service.py ├── role_service.py ├── permission_service.py ├── organization_service.py ├── department_service.py └── tenant_service.py随着业务越来越多,一个目录里堆满各种 Service、Repository,查找和维护都会变得越来越困难。
方案二:按业务模块划分(Feature-based)
另一种越来越流行的组织方式,就是按照业务模块划分目录。
例如:
app/ ├── modules/ │ ├── user/ │ ├── router.py │ ├── service.py │ ├── repository.py │ ├── model.py │ └── schema.py │ ├── post/ │ ├── router.py │ ├── service.py │ ├── repository.py │ ├── model.py │ └── schema.py │ ├── comment/ │ ├── router.py │ ├── service.py │ ├── repository.py │ ├── model.py │ └── schema.py │ ├── core/ ├── db/ └── main.py每一个业务模块都是一个相对独立的功能单元,它包含:
- 路由(Router)
- 业务逻辑(Service)
- 数据访问(Repository)
- 数据模型(Model)
- 请求响应对象(Schema)
所有与 User 有关的代码都放在同一个目录下。
例如修改用户功能,只需要进入:
user/ ├── router.py ├── service.py ├── repository.py ├── model.py └── schema.py基本不用再跨多个目录寻找文件。
为什么这样更合理?
因为现实开发过程中,代码的变化通常都是围绕业务发生的,而不是围绕技术层发生的。
例如,我们几乎不会说:
今天我要修改所有 Service。更多时候,我们会说:
今天新增用户注册功能。 今天修改订单支付流程。 今天增加角色权限管理。也就是说,代码的修改通常集中在某一个业务模块内。
因此,把同一个业务相关的代码放在一起,更符合日常开发习惯,也能降低维护成本。
推荐的 FastAPI 项目结构
目前很多 FastAPI 开源项目以及中大型 Python Web 项目都采用按业务模块组织代码。
例如:
app/ ├── core/ │ ├── config.py │ ├── security.py │ └── exception.py │ ├── db/ │ ├── session.py │ └── base.py │ ├── modules/ │ │ ├── user/ │ │ ├── router.py │ │ ├── service.py │ │ ├── repository.py │ │ ├── model.py │ │ └── schema.py │ │ ├── post/ │ │ ├── router.py │ │ ├── service.py │ │ ├── repository.py │ │ ├── model.py │ │ └── schema.py │ │ └── auth/ │ ├── router.py │ ├── service.py │ └── schema.py │ └── main.py其中:
- core:存放项目公共配置、安全认证、异常处理等基础设施
- db:数据库连接、Session 管理等
- modules:所有业务模块
- main.py:项目启动入口
这种组织方式既方便维护,也便于后续扩展。
如果项目继续变大怎么办?
当项目越来越复杂时,还可以进一步演进成 DDD(领域驱动设计)或者 Clean Architecture。
例如:
user/ ├── api/ │ └── router.py │ ├── application/ │ └── service.py │ ├── domain/ │ ├── entity.py │ └── repository.py │ └── infrastructure/ └── repository_impl.py不过,对于绝大多数 FastAPI 项目来说,直接引入完整的 DDD 分层往往会增加不少复杂度。
通常只有当项目规模足够大、业务领域非常复杂时,再逐步演进会更加合适。
总结
如果现在准备新建一个 FastAPI 项目,我更推荐采用按业务模块划分目录,例如:
app/ ├── core/ ├── db/ ├── modules/ │ ├── user/ │ ├── auth/ │ ├── post/ │ └── order/ └── main.py这样即使后续业务不断增加,也可以继续在模块内部拆分子目录,而不需要推倒整个项目结构重新设计。
对于小项目来说,按技术层划分完全没有问题;但如果希望项目具有更好的可维护性和扩展性,那么从一开始采用按业务模块组织代码,通常会是一个更好的选择。
最佳实践
这里推荐大家阅读一下FastAPI Best Practices这个开源项目:
https://github.com/zhanymkanov/fastapi-best-practices
该项目总结了大量 FastAPI 的工程实践,包括:
- 项目目录组织
- 路由拆分
- 依赖注入
- 异常处理
- 数据库管理
- 异步开发
- 测试规范
如果准备开发一个生产环境可用的 FastAPI 项目,非常值得阅读。
示例项目
我也基于本文介绍的架构整理并实现了一个FastAPI 种子项目,可以直接运行,帮助大家快速搭建属于自己的 FastAPI 项目。
项目地址:
https://github.com/byone421/fastapi-seed
既适合作为学习示例,也可以作为新项目初始化的脚手架。
结语
好的架构,并不是为了炫技,而是为了让未来的自己和团队成员能够更轻松地理解、维护和扩展项目。
希望本文能帮助你在设计 FastAPI 项目时少走一些弯路,也欢迎结合自己的实际项目,不断总结出最适合团队的架构方案。
