FastAPI 项目开发规范:项目结构、分层职责与代码约束
FastAPI 项目开发规范文档本文档用于指导基于 FastAPI 的 Python Web 项目开发约定项目结构、代码分层、编写规范和约束规则。适用于 Agent 类应用及通用后端服务。一、核心设计原则原则说明按业务模块分包按业务能力如user、agent、order组织代码而不是单纯按技术分层组织代码。每个模块包含自己的路由、模型、业务逻辑和数据访问。依赖方向单向依赖关系为业务模块 -core/公共基础设施。平级业务模块之间禁止直接相互调用避免循环依赖。如需跨模块调用通过core/层中转或使用事件机制解耦。Router 薄Service 厚Router 只做 HTTP 协议适配包括解析请求参数、调用 Service、返回响应。所有业务逻辑必须放在 Service 层。函数优先类为辅Service 层和 Repository 层优先使用独立函数不使用无状态类封装除非确实需要维护状态或需要利用继承、多态等能力。二、项目目录结构规范{project_name}/ ├── app/ │ ├── api/ # API 版本管理 │ │ └── v{version}/ # 版本号如 v1 │ │ └── endpoints/ # 路由端点按模块拆分 │ │ ├── {module1}.py # 如 user.py │ │ └── {module2}.py # 如 agent.py │ │ │ ├── core/ # 核心基础设施被所有业务模块依赖 │ │ ├── config.py # 配置管理使用 pydantic-settings │ │ ├── database.py # 数据库连接如异步引擎、会话工厂 │ │ ├── dependencies.py # 公共依赖注入如认证、分页 │ │ ├── exceptions.py # 自定义异常类 │ │ ├── response.py # 统一响应格式 │ │ └── {infra}.py # 其他基础设施如 LLM 客户端、Redis │ │ │ ├── modules/ # 业务模块核心代码 │ │ ├── {module1}/ # 如 user/ │ │ │ ├── schemas.py # Pydantic 模型请求/响应 │ │ │ ├── models.py # ORM 模型如 SQLAlchemy/Tortoise │ │ │ ├── service.py # 业务逻辑函数 │ │ │ └── repository.py # 数据访问函数 │ │ └── {module2}/ # 如 agent/ │ │ ├── schemas.py │ │ ├── models.py │ │ ├── service.py │ │ └── repository.py │ │ │ ├── main.py # FastAPI 应用入口 │ └── __init__.py │ ├── tests/ # 单元测试 │ └── {module}/ # 按模块组织 │ ├── test_service.py │ └── test_repository.py │ ├── .env # 环境变量不提交 Git ├── .env.example # 环境变量示例 ├── requirements.txt # 生产依赖 ├── requirements-dev.txt # 开发依赖 └── pyproject.toml # 项目配置三、各层级职责与约束3.1 Core 层位置app/core/职责提供全局配置、数据库连接、公共依赖、统一响应、异常基类等基础设施。不包含任何业务逻辑。可以被所有业务模块导入依赖。约束Core 层不得导入任何modules/下的模块保持底层独立。配置类必须从环境变量读取敏感信息不得硬编码。3.2 Modules 层3.2.1 Schemasschemas.py职责定义请求数据模型Request Schema。定义响应数据模型Response Schema。使用 PydanticBaseModel进行数据校验和序列化。约束不在 Schema 中编写任何业务逻辑或数据验证以外的代码。响应模型与 ORM 模型分离避免直接暴露数据库字段。使用from_attributes TruePydantic v2支持 ORM 对象转换。3.2.2 Modelsmodels.py职责定义数据库表结构ORM 模型。使用 SQLAlchemy 或其他 ORM 定义表字段、索引、关系。约束不在 Model 中添加业务逻辑方法。字段命名使用下划线风格snake_case。敏感字段如密码不应直接映射到响应 Schema。3.2.3 Repositoryrepository.py职责封装所有数据库 CRUD 操作。提供纯函数接口接收db会话作为参数。约束函数命名规范get_by_*、create_*、update_*、delete_*。不包含业务逻辑如密码加密、数据校验。所有函数为async异步函数。提交事务由调用方Service控制Repository 层不自行提交事务。3.2.4 Serviceservice.py职责包含所有核心业务逻辑。调用 Repository 进行数据操作。处理事务边界包括提交和回滚。调用外部服务如 LLM API、消息队列。约束使用独立函数不使用无状态类封装除非确实需要维护状态。每个业务场景对应一个独立函数。函数命名应清晰表达业务意图如register_user、chat_with_agent。使用async with AsyncSessionLocal() as db:管理数据库会话。正确处理异常并抛出明确的业务异常AppException子类。不直接返回 HTTP 响应只返回业务数据或抛出异常。3.3 API 层Router位置app/api/v{version}/endpoints/职责定义路由和 HTTP 方法如 GET、POST、PUT、DELETE 等。通过 Pydantic Schema 校验请求参数。调用 Service 层执行业务。格式化并返回统一响应。约束Router 中不包含任何业务逻辑只做协议适配。使用APIRouter并指定prefix和tags。使用Depends注入依赖如认证、数据库会话。异常统一转换为 HTTP 异常抛出由全局异常处理捕获。响应格式必须遵循统一的{code, message, data}结构。3.4 应用入口main.py职责创建 FastAPI 应用实例。注册路由。配置中间件如 CORS、日志等。注册全局异常处理。管理应用生命周期包括启动和关闭事件。约束使用lifespan上下文管理器管理资源。路由注册必须通过include_router进行。敏感配置从core/config.py读取。四、关键规范与约束4.1 导入规范正确from app.modules.user import service as user_service正确from app.core.database import get_db禁止业务模块之间直接相互导入如agent导入user禁止循环依赖如 A 导入 BB 又导入 A4.2 异步规范所有数据库操作、外部 API 调用必须使用async/await。同步阻塞代码如 CPU 密集型任务应通过run_in_threadpool放到线程池执行避免阻塞事件循环。4.3 异常处理规范业务异常继承AppException包含错误码和错误信息。Router 层捕获业务异常并转换为 HTTP 异常。全局异常处理器统一格式化错误响应。4.4 事务管理规范事务边界在 Service 层控制。使用async with AsyncSessionLocal() as db:管理会话生命周期。提交事务使用await db.commit()回滚使用await db.rollback()。禁止在 Repository 层自行提交事务。4.5 响应格式规范统一响应格式如下{code:0,message:success,data:{}}字段说明code状态码0表示成功非0表示失败。message提示信息。data业务数据。规范函数success(data, message)返回成功响应。error(message, code)返回错误响应。4.6 依赖注入规范公共依赖如认证定义在core/dependencies.py。使用 FastAPI 的Depends进行依赖注入。每个请求独立的依赖如数据库会话通过Depends(get_db)注入。4.7 测试规范单元测试按模块组织如tests/user/test_service.py。Service 层测试不依赖 HTTP 网络直接调用 Service 函数。使用pytest-asyncio支持异步测试。数据库测试使用独立的测试数据库或内存数据库。五、示例代码片段说明性5.1 Service 层函数签名示例# 正确使用独立函数asyncdefregister_user(data:UserCreateSchema)-UserModel:用户注册业务逻辑asyncwithAsyncSessionLocal()asdb:# 业务逻辑代码...# 错误不推荐使用无状态类classUserService:staticmethodasyncdefregister_user(data:UserCreateSchema)-UserModel:...5.2 Router 层调用示例# 正确Router 薄只做适配router.post(/register)asyncdefregister(data:UserCreateSchema):try:userawaituser_service.register_user(data)returnsuccess(dataUserResponseSchema.model_validate(user))exceptUserAlreadyExistsErrorase:raiseHTTPException(status_code400,detailstr(e))5.3 依赖注入示例# Core 层定义公共依赖asyncdefget_current_user(credentials:HTTPAuthorizationCredentialsDepends(security)):...# Router 层使用依赖router.get(/profile)asyncdefget_profile(current_userDepends(get_current_user)):...5.4 事务管理示例# 正确Service 层控制事务asyncdefupdate_user(user_id:int,data:dict):asyncwithAsyncSessionLocal()asdb:userawaituser_repo.get_by_id(db,user_id)ifnotuser:raiseUserNotFoundError()userawaituser_repo.update(db,user_id,data)awaitdb.commit()returnuser# 错误Repository 层自行提交事务asyncdefupdate(db,user_id,data):...# 不该在这里 commitawaitdb.commit()六、环境变量配置规范所有敏感配置如数据库 URL、API Key、Secret必须从环境变量读取。使用pydantic-settings管理配置。提供.env.example文件列出所有需要的环境变量并去掉真实值。七、代码检查清单提交代码前确认以下事项新功能是否按业务模块分包Service 层是否使用了独立函数而不是无状态类Router 中是否包含业务逻辑业务逻辑应放在 Service 中。是否避免了模块间的循环导入是否编写了对应的单元测试是否正确管理了数据库事务包括 Service 层的 commit/rollbackAPI 响应是否使用了统一格式{code, message, data}敏感信息是否从环境变量读取而不是硬编码是否添加了必要的异常处理和全局异常处理器异步函数是否使用了正确的async/await语法本规范是项目约定所有代码应遵守。如有特殊场景需要偏离规范需在代码审查时说明理由并获得批准。

相关新闻

人力资源管理系统大屏可视化项目:核心难点与优化实践

人力资源管理系统大屏可视化项目:核心难点与优化实践

项目概述本文基于一个实际的人力资源管理系统大屏可视化项目,深入剖析在复杂业务场景下面临的技术挑战及相应的优化方案。该项目采用 Vue ECharts 技术栈,包含人员分析、主题分析两大模块,涉及 3D 图表渲染、多图表联动、响应式布局等复杂功…

2026/10/11 23:41:55 阅读更多 →
Windows驱动数字签名错误解决:威龙舵机驱动板安装排毒指南

Windows驱动数字签名错误解决:威龙舵机驱动板安装排毒指南

1. 项目概述:从“排毒”到“重生”的硬件驱动之旅 最近在折腾一个老项目,用到了威龙(Wellon)的24路舵机驱动板。这玩意儿在机器人、自动化控制领域挺常见的,一块板子能集中控制24个舵机,对于做机械臂或者复…

2026/10/11 23:41:59 阅读更多 →
开源 AI 模型到底该不该禁?Anthropic 的一场“不情愿的澄清“,撕开了硅谷最深的裂痕

开源 AI 模型到底该不该禁?Anthropic 的一场“不情愿的澄清“,撕开了硅谷最深的裂痕

上周,25 家科技巨头联名给白宫写了一封信,要求"不要过早限制开源 AI 模型"。发信者包括 Nvidia、Microsoft、Meta、IBM、Hugging Face——Nvidia 的黄仁勋甚至为此发出了他人生中第一条 X。 但有一家公司的名字没有出现在签名栏里:…

2026/10/5 17:42:36 阅读更多 →

最新新闻

黑科技下载器源码实战:多线程分块、断点续传与资源嗅探全解析

黑科技下载器源码实战:多线程分块、断点续传与资源嗅探全解析

简介:黑科下载器是一款面向普通用户的多端下载工具资源包,针对迅雷限速、百度云非会员龟速等常见痛点,提供网页版、PC端、安卓与iOS四种使用形态,适合希望摆脱会员限制、提升日常下载效率的用户参考使用。压缩包共267个文件&#…

2026/10/11 23:41:48 阅读更多 →
窗口函数 SUM() OVER() 详解:PARTITION BY 与 ORDER BY 的累计计算逻辑

窗口函数 SUM() OVER() 详解:PARTITION BY 与 ORDER BY 的累计计算逻辑

很多人学了窗口函数,一看到SUM() OVER(PARTITION BY ... ORDER BY ...)这种写法还是会懵,特别是ORDER BY加上之后,结果怎么就从“分组总和”变成“累加值”了?这篇文章继续走实战路线,我会把SUM() OVER()从基础语法到进…

2026/10/11 23:40:47 阅读更多 →
数据库课程设计:电力收费系统表结构、触发器与存储过程全解析

数据库课程设计:电力收费系统表结构、触发器与存储过程全解析

简介:《数据库课程设计电力公司收费系统.doc》是一份完整的数据库课程设计报告,面向高校计算机、软件工程等专业学生,适用于电力公司收费管理信息系统设计课题。文档围绕客户、用电类型、员工、用电信息、费用管理、收费登记六大核心数据表展…

2026/10/11 23:40:47 阅读更多 →
JMeter+InfluxDB+Grafana:搭建性能测试实时监控看板

JMeter+InfluxDB+Grafana:搭建性能测试实时监控看板

做性能测试的人基本都经历过这样的场景:JMeter压着压着,突然想知道当前的TPS到底有没有掉链子,响应时间的曲线是不是已经拐头向上,可日志刷得太快根本看不出来。一开始我也用JMeter自带的监听器,结果压测刚跑几分钟&am…

2026/10/11 23:40:47 阅读更多 →
内网安全评估:揭秘ACL权限滥用与横向移动链路

内网安全评估:揭秘ACL权限滥用与横向移动链路

内网安全评估做到第三周的时候,我在一份共享文件夹的ACL导出清单里看到了一个非常扎眼的组名:SHARE MODERATORS。这个组在域里并不显眼,不在本地管理员组,也不在任何域管理组里,可它的权限范围却覆盖了全公司的核心共享…

2026/10/11 23:40:47 阅读更多 →
同城家政服务平台搭建,多商户派单方案详解

同城家政服务平台搭建,多商户派单方案详解

同城家政服务平台搭建:多商户入驻与智能派单方案详解同城家政行业早已从单一门店自营模式,转向多商户平台化联营发展。平台整合全城多家家政公司、个体服务商、持证服务师傅,统一承接用户订单,通过智能调度完成订单分发与履约。相…

2026/10/11 23:39:46 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →