|
|
|
|
@ -0,0 +1,594 @@
|
|
|
|
|
---
|
|
|
|
|
alwaysApply: true
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# 后端项目开发规范 (Flask + APIFlask)
|
|
|
|
|
|
|
|
|
|
## 项目架构
|
|
|
|
|
|
|
|
|
|
本项目基于 **Flask + APIFlask** 框架,使用以下技术栈:
|
|
|
|
|
- **Web框架**: Flask + APIFlask (API文档自动生成)
|
|
|
|
|
- **ORM**: SQLAlchemy
|
|
|
|
|
- **数据库迁移**: Flask-Migrate (Alembic)
|
|
|
|
|
- **认证**: Flask-JWT-Extended
|
|
|
|
|
- **序列化**: Marshmallow
|
|
|
|
|
- **限流**: Flask-Limiter
|
|
|
|
|
- **缓存**: Flask-Caching
|
|
|
|
|
- **事件系统**: 自定义事件总线
|
|
|
|
|
|
|
|
|
|
参考文件:
|
|
|
|
|
- @file:iti/app.py
|
|
|
|
|
- @file:iti/applications/__init__.py
|
|
|
|
|
- @file:iti/config.py
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
iti/applications/
|
|
|
|
|
├── __init__.py # 应用工厂函数
|
|
|
|
|
├── common/ # 公共模块
|
|
|
|
|
│ ├── crud.py # CRUD 基础操作
|
|
|
|
|
│ ├── enums.py # 枚举定义
|
|
|
|
|
│ ├── exceptions/ # 异常定义
|
|
|
|
|
│ ├── utils/ # 工具函数
|
|
|
|
|
│ └── storage/ # 文件存储
|
|
|
|
|
├── models/ # 数据模型
|
|
|
|
|
│ ├── schema/ # Schema 定义
|
|
|
|
|
│ └── *.py # 模型文件
|
|
|
|
|
├── routes/ # 路由定义
|
|
|
|
|
│ ├── sys/ # 系统管理路由
|
|
|
|
|
│ └── schemas/ # 请求/响应 Schema
|
|
|
|
|
├── service/ # 业务逻辑层
|
|
|
|
|
├── extensions/ # 扩展初始化
|
|
|
|
|
└── events/ # 事件处理器
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 代码规范
|
|
|
|
|
|
|
|
|
|
### 1. 应用工厂模式
|
|
|
|
|
|
|
|
|
|
使用应用工厂函数创建 Flask 应用:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications import create_app
|
|
|
|
|
|
|
|
|
|
app = create_app(config_name='dev')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/__init__.py
|
|
|
|
|
|
|
|
|
|
### 2. 配置管理规范
|
|
|
|
|
|
|
|
|
|
#### 配置类继承结构
|
|
|
|
|
```python
|
|
|
|
|
class BaseConfig:
|
|
|
|
|
"""基础配置类 - 所有环境共享的配置"""
|
|
|
|
|
# 基础配置项
|
|
|
|
|
|
|
|
|
|
class DevConfig(BaseConfig):
|
|
|
|
|
"""开发环境配置"""
|
|
|
|
|
DEBUG = True
|
|
|
|
|
|
|
|
|
|
class ProdConfig(BaseConfig):
|
|
|
|
|
"""生产环境配置"""
|
|
|
|
|
DEBUG = False
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 环境变量加载
|
|
|
|
|
- 使用 `python-dotenv` 加载 `.env` 文件
|
|
|
|
|
- 优先级:`.env.local` > `.env.{FLASK_ENV}` > `.env`
|
|
|
|
|
- 敏感配置必须使用环境变量
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/config.py
|
|
|
|
|
|
|
|
|
|
### 3. 数据模型规范
|
|
|
|
|
|
|
|
|
|
#### 模型基类
|
|
|
|
|
所有模型继承 `BaseModelMixin`:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.crud import BaseModelMixin
|
|
|
|
|
from iti.applications.extensions import db
|
|
|
|
|
|
|
|
|
|
class User(BaseModelMixin):
|
|
|
|
|
__tablename__ = "sys_user"
|
|
|
|
|
|
|
|
|
|
username = db.Column(db.String(64), nullable=False, comment="用户名")
|
|
|
|
|
# 其他字段...
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**BaseModelMixin 包含**:
|
|
|
|
|
- `id`: UUID 主键(自动生成)
|
|
|
|
|
- `created_at`: 创建时间
|
|
|
|
|
- `updated_at`: 更新时间
|
|
|
|
|
- `created_by`: 创建人
|
|
|
|
|
- `updated_by`: 更新人
|
|
|
|
|
- `remark`: 备注
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/crud.py
|
|
|
|
|
- @file:iti/applications/models/sys_user.py
|
|
|
|
|
|
|
|
|
|
#### 模型关系定义
|
|
|
|
|
```python
|
|
|
|
|
# 多对多关系
|
|
|
|
|
roles = db.relationship(
|
|
|
|
|
"Role",
|
|
|
|
|
secondary="sys_user_role",
|
|
|
|
|
back_populates="users",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 一对多关系
|
|
|
|
|
children = db.relationship(
|
|
|
|
|
"SysDept",
|
|
|
|
|
backref="parent",
|
|
|
|
|
lazy="dynamic",
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4. Schema 序列化规范
|
|
|
|
|
|
|
|
|
|
#### Schema 定义
|
|
|
|
|
使用 Marshmallow Schema 进行序列化/反序列化:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.utils import BaseSchema
|
|
|
|
|
from apiflask.fields import String, DateTime, Enum, Nested
|
|
|
|
|
|
|
|
|
|
class UserSchema(BaseSchema):
|
|
|
|
|
id = String()
|
|
|
|
|
username = String()
|
|
|
|
|
created_at = DateTime(data_key="createdAt", format="%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
|
|
|
|
# 关系字段
|
|
|
|
|
roles = Nested("RoleSchema", many=True, dump_only=True)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**命名规范**:
|
|
|
|
|
- 响应字段使用 camelCase(通过 `data_key` 转换)
|
|
|
|
|
- 时间字段格式:`%Y-%m-%d %H:%M:%S`
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/models/sys_user.py
|
|
|
|
|
|
|
|
|
|
### 5. 路由定义规范
|
|
|
|
|
|
|
|
|
|
#### Blueprint 创建
|
|
|
|
|
使用 APIFlask 的 APIBlueprint:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from apiflask import APIBlueprint
|
|
|
|
|
from iti.applications.common.utils import success
|
|
|
|
|
from iti.applications.extensions import db
|
|
|
|
|
|
|
|
|
|
bp = APIBlueprint("module_name", __name__, url_prefix="/api/xxx", tag="模块.子模块")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 路由装饰器
|
|
|
|
|
```python
|
|
|
|
|
@bp.post("/create")
|
|
|
|
|
@bp.input(CreateRequest.Schema, location="json")
|
|
|
|
|
@bp.output(ResponseSchema)
|
|
|
|
|
@jwt_required()
|
|
|
|
|
@sys_log(name="创建", desc="创建xxx", type=LogType.OPERATION)
|
|
|
|
|
def create(json_data: CreateRequest):
|
|
|
|
|
"""创建资源"""
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
return success(data, message="创建成功")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**装饰器顺序**:
|
|
|
|
|
1. `@bp.method("/path")` - 路由定义
|
|
|
|
|
2. `@bp.input()` - 请求验证
|
|
|
|
|
3. `@bp.output()` - 响应定义
|
|
|
|
|
4. `@jwt_required()` - 认证
|
|
|
|
|
5. `@sys_log()` - 日志记录
|
|
|
|
|
6. `@limiter.limit()` - 限流(如需要)
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/routes/sys/auth.py
|
|
|
|
|
- @file:iti/applications/routes/__init__.py
|
|
|
|
|
|
|
|
|
|
### 6. 请求/响应 Schema 规范
|
|
|
|
|
|
|
|
|
|
#### 请求 Schema
|
|
|
|
|
```python
|
|
|
|
|
from apiflask.fields import String, Integer
|
|
|
|
|
from marshmallow import validate
|
|
|
|
|
|
|
|
|
|
class CreateRequest(ma.Schema):
|
|
|
|
|
username = String(
|
|
|
|
|
required=True,
|
|
|
|
|
validate=validate.Length(min=3, max=64),
|
|
|
|
|
metadata={"description": "用户名"}
|
|
|
|
|
)
|
|
|
|
|
email = String(
|
|
|
|
|
validate=validate.Email(),
|
|
|
|
|
metadata={"description": "邮箱"}
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 响应 Schema
|
|
|
|
|
使用模型 Schema 或自定义 Schema:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
@bp.output(UserSchema)
|
|
|
|
|
# 或
|
|
|
|
|
@bp.output(ma.Schema)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 7. 业务逻辑层规范
|
|
|
|
|
|
|
|
|
|
#### Service 层职责
|
|
|
|
|
- 复杂的业务逻辑处理
|
|
|
|
|
- 跨模型的操作
|
|
|
|
|
- 缓存逻辑
|
|
|
|
|
- 外部服务调用
|
|
|
|
|
|
|
|
|
|
#### Service 文件组织
|
|
|
|
|
```python
|
|
|
|
|
# service/sys_user.py
|
|
|
|
|
from iti.applications.models import User
|
|
|
|
|
from iti.applications.extensions import db
|
|
|
|
|
|
|
|
|
|
def get_user_by_id(user_id: str) -> User:
|
|
|
|
|
"""根据ID获取用户"""
|
|
|
|
|
return db.session.scalar(select(User).filter_by(id=user_id))
|
|
|
|
|
|
|
|
|
|
def create_user(data: dict) -> User:
|
|
|
|
|
"""创建用户"""
|
|
|
|
|
user = User(**data)
|
|
|
|
|
db.session.add(user)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
return user
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/service/sys_config.py
|
|
|
|
|
|
|
|
|
|
### 8. 异常处理规范
|
|
|
|
|
|
|
|
|
|
#### 业务异常
|
|
|
|
|
使用 `BizException` 抛出业务异常:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.exceptions.biz_exp import BizException
|
|
|
|
|
|
|
|
|
|
if user is None:
|
|
|
|
|
raise BizException("用户不存在")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 异常响应格式
|
|
|
|
|
异常会自动转换为 JSON 响应:
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"code": 400,
|
|
|
|
|
"message": "用户不存在",
|
|
|
|
|
"detail": {}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/exceptions/biz_exp.py
|
|
|
|
|
- @file:iti/applications/extensions/error_handler.py
|
|
|
|
|
|
|
|
|
|
### 9. 数据库操作规范
|
|
|
|
|
|
|
|
|
|
#### 查询操作
|
|
|
|
|
使用 SQLAlchemy 2.0 风格:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from sqlalchemy import select
|
|
|
|
|
|
|
|
|
|
# 单条查询
|
|
|
|
|
user = db.session.scalar(select(User).filter_by(id=user_id))
|
|
|
|
|
|
|
|
|
|
# 多条查询
|
|
|
|
|
users = db.session.scalars(select(User).filter_by(status="enabled")).all()
|
|
|
|
|
|
|
|
|
|
# 关联查询
|
|
|
|
|
user = db.session.scalar(
|
|
|
|
|
select(User)
|
|
|
|
|
.filter_by(id=user_id)
|
|
|
|
|
.options(joinedload(User.roles))
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 事务处理
|
|
|
|
|
```python
|
|
|
|
|
try:
|
|
|
|
|
db.session.add(user)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
db.session.rollback()
|
|
|
|
|
raise BizException("创建失败")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 10. 认证和授权规范
|
|
|
|
|
|
|
|
|
|
#### JWT 认证
|
|
|
|
|
使用 `@jwt_required()` 装饰器:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from flask_jwt_extended import jwt_required, current_user
|
|
|
|
|
|
|
|
|
|
@bp.get("/profile")
|
|
|
|
|
@jwt_required()
|
|
|
|
|
def get_profile():
|
|
|
|
|
"""获取当前用户信息"""
|
|
|
|
|
return success(current_user)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 权限检查
|
|
|
|
|
使用 `@permission_required()` 装饰器:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.permission import permission_required
|
|
|
|
|
|
|
|
|
|
@bp.delete("/delete")
|
|
|
|
|
@jwt_required()
|
|
|
|
|
@permission_required("sys:user:delete")
|
|
|
|
|
def delete_user(user_id: str):
|
|
|
|
|
"""删除用户"""
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/permission.py
|
|
|
|
|
|
|
|
|
|
### 11. 日志记录规范
|
|
|
|
|
|
|
|
|
|
#### 系统日志装饰器
|
|
|
|
|
使用 `@sys_log()` 装饰器记录操作日志:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.extensions import sys_log
|
|
|
|
|
from iti.applications.common.enums import LogType
|
|
|
|
|
|
|
|
|
|
@sys_log(
|
|
|
|
|
name="创建用户",
|
|
|
|
|
desc="创建新用户",
|
|
|
|
|
type=LogType.OPERATION,
|
|
|
|
|
save_db=True,
|
|
|
|
|
execute_time=True,
|
|
|
|
|
)
|
|
|
|
|
def create_user():
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/extensions/sys_log.py
|
|
|
|
|
|
|
|
|
|
### 12. 限流规范
|
|
|
|
|
|
|
|
|
|
#### 限流装饰器
|
|
|
|
|
使用 `@limiter.limit()` 装饰器:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.extensions.limit import limiter
|
|
|
|
|
|
|
|
|
|
@bp.post("/sendCode")
|
|
|
|
|
@limiter.limit(limit_value="2 per minute")
|
|
|
|
|
def send_code():
|
|
|
|
|
"""发送验证码"""
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/extensions/limit.py
|
|
|
|
|
|
|
|
|
|
### 13. 缓存使用规范
|
|
|
|
|
|
|
|
|
|
#### 缓存装饰器
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.extensions import cache_simple
|
|
|
|
|
|
|
|
|
|
@cache_simple.cached(timeout=300, key_prefix="user_")
|
|
|
|
|
def get_user_info(user_id: str):
|
|
|
|
|
"""获取用户信息(带缓存)"""
|
|
|
|
|
return db.session.scalar(select(User).filter_by(id=user_id))
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 手动缓存操作
|
|
|
|
|
```python
|
|
|
|
|
cache_simple.set(key="cache_key", value=data, timeout=300)
|
|
|
|
|
cached_data = cache_simple.get(key="cache_key")
|
|
|
|
|
cache_simple.delete(key="cache_key")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/extensions/cache.py
|
|
|
|
|
|
|
|
|
|
### 14. 文件存储规范
|
|
|
|
|
|
|
|
|
|
#### 文件上传
|
|
|
|
|
使用统一的文件存储接口:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.storage.manager import storage_manager
|
|
|
|
|
|
|
|
|
|
file_url = storage_manager.save(
|
|
|
|
|
file=request.files['file'],
|
|
|
|
|
folder="uploads",
|
|
|
|
|
filename="custom_name.jpg"
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/storage/manager.py
|
|
|
|
|
|
|
|
|
|
### 15. 事件系统规范
|
|
|
|
|
|
|
|
|
|
#### 事件定义
|
|
|
|
|
在 `common/events.py` 中定义事件:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
class UserEvents(Enum):
|
|
|
|
|
USER_REGISTERED = "user.registered"
|
|
|
|
|
USER_LOGGED_IN = "user.logged_in"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 事件触发
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.extensions import eventbus
|
|
|
|
|
from iti.applications.common.events import UserEvents
|
|
|
|
|
|
|
|
|
|
eventbus.emit(UserEvents.USER_REGISTERED.value, user)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 事件处理
|
|
|
|
|
在 `events/` 目录创建事件处理器:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.extensions.eventbus import event_handler
|
|
|
|
|
|
|
|
|
|
@event_handler("user.registered")
|
|
|
|
|
def on_user_registered(user, **kwargs):
|
|
|
|
|
"""用户注册事件处理"""
|
|
|
|
|
# 处理逻辑
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/events.py
|
|
|
|
|
- @file:iti/applications/events/user_cache_event_handler.py
|
|
|
|
|
|
|
|
|
|
### 16. 数据库迁移规范
|
|
|
|
|
|
|
|
|
|
#### 创建迁移
|
|
|
|
|
```bash
|
|
|
|
|
flask db migrate -m "描述信息"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 执行迁移
|
|
|
|
|
```bash
|
|
|
|
|
flask db upgrade
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 回滚迁移
|
|
|
|
|
```bash
|
|
|
|
|
flask db downgrade
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:migrations/README
|
|
|
|
|
|
|
|
|
|
### 17. 响应格式规范
|
|
|
|
|
|
|
|
|
|
#### 成功响应
|
|
|
|
|
使用 `success()` 函数:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.utils import success
|
|
|
|
|
|
|
|
|
|
return success(data, message="操作成功")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
响应格式:
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"code": 200,
|
|
|
|
|
"data": {...},
|
|
|
|
|
"message": "操作成功"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 错误响应
|
|
|
|
|
通过异常自动处理,或手动返回:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from iti.applications.common.utils import error
|
|
|
|
|
|
|
|
|
|
return error(message="错误信息", code=400)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 18. 枚举定义规范
|
|
|
|
|
|
|
|
|
|
在 `common/enums.py` 中定义枚举:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
from enum import Enum
|
|
|
|
|
|
|
|
|
|
class StatusEnum(str, Enum):
|
|
|
|
|
ENABLED = "enabled"
|
|
|
|
|
DISABLED = "disabled"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在模型中使用:
|
|
|
|
|
```python
|
|
|
|
|
status = db.Column(
|
|
|
|
|
db.Enum(StatusEnum, values_callable=lambda x: [e.value for e in x]),
|
|
|
|
|
nullable=False,
|
|
|
|
|
default=StatusEnum.ENABLED.value,
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/enums.py
|
|
|
|
|
|
|
|
|
|
### 19. 工具函数规范
|
|
|
|
|
|
|
|
|
|
#### 通用工具
|
|
|
|
|
放在 `common/utils/` 目录:
|
|
|
|
|
- `http.py`: HTTP 响应工具
|
|
|
|
|
- `validate.py`: 验证工具
|
|
|
|
|
- `cache.py`: 缓存工具
|
|
|
|
|
- `tree.py`: 树形结构工具
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:iti/applications/common/utils/http.py
|
|
|
|
|
|
|
|
|
|
### 20. API 文档规范
|
|
|
|
|
|
|
|
|
|
#### 自动生成文档
|
|
|
|
|
APIFlask 自动生成 API 文档,访问:
|
|
|
|
|
- Swagger UI: `/docs`
|
|
|
|
|
- ReDoc: `/docs`
|
|
|
|
|
- Elements: `/docs` (默认)
|
|
|
|
|
|
|
|
|
|
#### 文档注解
|
|
|
|
|
使用 docstring 和 metadata:
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
@bp.post("/create")
|
|
|
|
|
@bp.input(CreateRequest.Schema, location="json")
|
|
|
|
|
def create(json_data: CreateRequest):
|
|
|
|
|
"""
|
|
|
|
|
创建资源
|
|
|
|
|
|
|
|
|
|
这是创建资源的接口,用于...
|
|
|
|
|
"""
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 开发注意事项
|
|
|
|
|
|
|
|
|
|
1. **事务管理**: 确保数据库操作在事务中,异常时回滚
|
|
|
|
|
2. **N+1 查询**: 使用 `joinedload` 或 `selectinload` 避免 N+1 问题
|
|
|
|
|
3. **SQL 注入**: 使用参数化查询,不要拼接 SQL
|
|
|
|
|
4. **性能优化**: 合理使用缓存,避免重复查询
|
|
|
|
|
5. **错误处理**: 所有异常都要有适当的处理,不要暴露敏感信息
|
|
|
|
|
6. **日志记录**: 重要操作都要记录日志,便于排查问题
|
|
|
|
|
7. **类型提示**: 使用 Type Hints 提高代码可读性
|
|
|
|
|
8. **代码复用**: 公共逻辑提取到 service 或 utils
|
|
|
|
|
|
|
|
|
|
## 测试规范
|
|
|
|
|
|
|
|
|
|
### 单元测试
|
|
|
|
|
- 测试文件放在 `tests/` 目录
|
|
|
|
|
- 测试文件命名:`test_*.py`
|
|
|
|
|
- 使用 pytest 框架
|
|
|
|
|
|
|
|
|
|
### 测试示例
|
|
|
|
|
```python
|
|
|
|
|
def test_create_user(client):
|
|
|
|
|
response = client.post('/api/user', json={
|
|
|
|
|
'username': 'test',
|
|
|
|
|
'email': 'test@example.com'
|
|
|
|
|
})
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
参考:
|
|
|
|
|
- @file:tests/test_http_utils.py
|