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/7/29 9:39:18阅读更多 →
Windows驱动数字签名错误解决:威龙舵机驱动板安装排毒指南

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

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

2026/7/29 9:39:18阅读更多 →
基于51单片机的电子密码锁:从硬件设计到软件实现的完整项目指南

基于51单片机的电子密码锁:从硬件设计到软件实现的完整项目指南

1. 项目缘起:为什么51单片机依然是电子密码锁的经典选择最近在整理工作室的旧项目资料,翻出了一个大学时期做的电子密码锁,用的就是最经典的STC89C52RC单片机。当时觉得这玩意儿功能简单,现在回头再看,发现它其实是一个…

2026/7/29 9:37:17阅读更多 →
SpringBoot生鲜团购平台高并发架构实战

SpringBoot生鲜团购平台高并发架构实战

1. 项目概述:生鲜团购平台的技术架构选型生鲜团购平台作为社区电商的典型应用,需要应对高并发订单、实时库存更新和短时效商品管理等特殊挑战。选择SpringBoot作为基础框架并非偶然——其快速启动特性完美适配生鲜行业"晨采午达"的业务节奏&am…

2026/7/29 10:55:36阅读更多 →
Flink生产实战:从窗口乱序处理到CDC管道构建与作业运维

Flink生产实战:从窗口乱序处理到CDC管道构建与作业运维

1. 从“四大基石”到“生产实战”:为什么你的Flink学习不能止步于Demo如果你已经跟着上一篇笔记,把Flink的编程模型、DataStream API和状态管理这些基础概念都过了一遍,甚至自己动手写了几个WordCount或者实时统计的Demo,感觉已经…

2026/7/29 10:55:36阅读更多 →
图论算法进阶:严格与非严格次短路的Dijkstra求解与应用

图论算法进阶:严格与非严格次短路的Dijkstra求解与应用

1. 从“最短”到“次短”:一个被低估的图论问题在算法竞赛和实际的路由规划、网络分析中,我们最常打交道的是“最短路”问题。Dijkstra、Bellman-Ford、SPFA这些名字,对于任何一个接触过图论的人来说都如雷贯耳。我们习惯于寻找从A点到B点的最…

2026/7/29 10:55:36阅读更多 →
基于Bluno Mega与蓝牙手柄的无线交互原型开发实战

基于Bluno Mega与蓝牙手柄的无线交互原型开发实战

1. 项目缘起:从“遥控灯”到“无线交互原型”的思考 那天在工作室整理零件,手边正好有一个闲置的Bluno Mega 2560开发板、一个蓝牙手柄,还有几颗LED。一个很自然的想法冒了出来:能不能用手柄来控制这些灯?这听起来像是…

2026/7/29 10:55:36阅读更多 →
为HuskyLens AI视觉模块设计3D打印可定制外壳:从建模到实现的完整指南

为HuskyLens AI视觉模块设计3D打印可定制外壳:从建模到实现的完整指南

1. 项目缘起:当AI视觉模块遇上“二哈”灵魂 如果你玩过DFRobot的HuskyLens,大概率会对这个方形的小家伙又爱又“恨”。爱的是它把复杂的AI视觉(人脸识别、物体追踪、颜色识别等)封装得如此易用,一个KNN算法学习键就能让…

2026/7/29 10:55:36阅读更多 →
思源宋体CN:7种字重免费字体如何彻底改变你的中文设计体验

思源宋体CN:7种字重免费字体如何彻底改变你的中文设计体验

思源宋体CN:7种字重免费字体如何彻底改变你的中文设计体验 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为中文设计找不到合适的免费字体而烦恼吗?思源宋…

2026/7/29 10:53:36阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“! 在构建复杂的 Agent 系统时,我们经常会遇到这样的场景:Agent 正在执行一个多步骤的任务,比如“下单购买商品”,但执行到一半时,我们…

2026/7/29 0:01:46阅读更多 →
自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…

2026/7/29 0:01:46阅读更多 →
【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:01:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/29 4:31:51阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →