469 lines
9.9 KiB
Markdown
469 lines
9.9 KiB
Markdown
# DESIGN - 完善 CRUD API 功能系统设计
|
|
|
|
## 整体架构图
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph "API 层"
|
|
A1[GET /api/v1/users/]
|
|
A2[POST /api/v1/users/]
|
|
A3[PUT /api/v1/users/{id}]
|
|
A4[DELETE /api/v1/users/{id}]
|
|
A5[GET /api/v1/products/]
|
|
A6[POST /api/v1/products/]
|
|
A7[PUT /api/v1/products/{id}]
|
|
A8[DELETE /api/v1/products/{id}]
|
|
end
|
|
|
|
subgraph "请求验证层"
|
|
B1[UserCreate Schema]
|
|
B2[UserUpdate Schema]
|
|
B3[ProductCreate Schema]
|
|
B4[ProductUpdate Schema]
|
|
B5[Response Schemas]
|
|
end
|
|
|
|
subgraph "服务层"
|
|
C1[UserService]
|
|
C2[ProductService]
|
|
end
|
|
|
|
subgraph "数据访问层"
|
|
D1[SQLAlchemy Session]
|
|
D2[Database Models]
|
|
end
|
|
|
|
subgraph "数据库层"
|
|
E1[(MySQL fast_demo)]
|
|
E2[users table]
|
|
E3[products table]
|
|
end
|
|
|
|
A1 --> B5
|
|
A2 --> B1
|
|
A3 --> B2
|
|
A4 --> B5
|
|
A5 --> B5
|
|
A6 --> B3
|
|
A7 --> B4
|
|
A8 --> B5
|
|
|
|
B1 --> C1
|
|
B2 --> C1
|
|
B3 --> C2
|
|
B4 --> C2
|
|
B5 --> C1
|
|
B5 --> C2
|
|
|
|
C1 --> D1
|
|
C2 --> D1
|
|
D1 --> D2
|
|
D2 --> E1
|
|
E1 --> E2
|
|
E1 --> E3
|
|
```
|
|
|
|
## 分层设计
|
|
|
|
### 1. API 路由层 (app/api/v1/endpoints/)
|
|
|
|
#### 职责
|
|
- HTTP 请求路由处理
|
|
- 请求参数验证
|
|
- 响应状态码设置
|
|
- 依赖注入管理
|
|
|
|
#### 核心组件
|
|
- **users.py**: 用户相关 API 端点
|
|
- **products.py**: 产品相关 API 端点
|
|
|
|
#### 设计原则
|
|
- 轻量级路由,业务逻辑下沉到服务层
|
|
- 统一的异常处理
|
|
- 依赖注入数据库会话
|
|
|
|
### 2. 数据验证层 (app/schemas/)
|
|
|
|
#### 职责
|
|
- 请求数据验证
|
|
- 响应数据序列化
|
|
- 数据类型转换
|
|
|
|
#### 现有模式
|
|
- **UserCreate**: 创建用户请求数据
|
|
- **UserUpdate**: 更新用户请求数据
|
|
- **UserResponse**: 用户响应数据
|
|
- **ProductCreate**: 创建产品请求数据
|
|
- **ProductUpdate**: 更新产品请求数据
|
|
- **ProductResponse**: 产品响应数据
|
|
|
|
### 3. 业务服务层 (app/services/)
|
|
|
|
#### 职责
|
|
- 业务逻辑实现
|
|
- 数据库 CRUD 操作
|
|
- 业务规则验证
|
|
- 异常处理和转换
|
|
|
|
#### 核心服务类
|
|
- **UserService**: 用户业务逻辑
|
|
- **ProductService**: 产品业务逻辑
|
|
|
|
#### 设计模式
|
|
- 依赖注入数据库会话
|
|
- 静态方法实现具体操作
|
|
- 统一的异常处理
|
|
|
|
### 4. 数据访问层 (app/database/)
|
|
|
|
#### 职责
|
|
- 数据库连接管理
|
|
- ORM 模型定义
|
|
- 会话生命周期管理
|
|
|
|
#### 核心组件
|
|
- **connection.py**: 数据库连接和会话管理
|
|
- **models.py**: SQLAlchemy 数据库模型
|
|
- **base.py**: Base 模型类
|
|
|
|
## 核心组件设计
|
|
|
|
### UserService 重构设计
|
|
|
|
```python
|
|
class UserService:
|
|
@staticmethod
|
|
def get_all_users(db: Session) -> List[User]:
|
|
"""获取所有用户"""
|
|
|
|
@staticmethod
|
|
def get_user_by_id(db: Session, user_id: int) -> Optional[User]:
|
|
"""根据ID获取用户"""
|
|
|
|
@staticmethod
|
|
def create_user(db: Session, user_data: UserCreate) -> User:
|
|
"""创建新用户"""
|
|
|
|
@staticmethod
|
|
def update_user(db: Session, user_id: int, user_data: UserUpdate) -> Optional[User]:
|
|
"""更新用户信息"""
|
|
|
|
@staticmethod
|
|
def delete_user(db: Session, user_id: int) -> bool:
|
|
"""删除用户"""
|
|
```
|
|
|
|
### ProductService 重构设计
|
|
|
|
```python
|
|
class ProductService:
|
|
@staticmethod
|
|
def get_all_products(db: Session) -> List[Product]:
|
|
"""获取所有产品"""
|
|
|
|
@staticmethod
|
|
def get_product_by_id(db: Session, product_id: int) -> Optional[Product]:
|
|
"""根据ID获取产品"""
|
|
|
|
@staticmethod
|
|
def create_product(db: Session, product_data: ProductCreate) -> Product:
|
|
"""创建新产品"""
|
|
|
|
@staticmethod
|
|
def update_product(db: Session, product_id: int, product_data: ProductUpdate) -> Optional[Product]:
|
|
"""更新产品信息"""
|
|
|
|
@staticmethod
|
|
def delete_product(db: Session, product_id: int) -> bool:
|
|
"""删除产品"""
|
|
```
|
|
|
|
## 模块依赖关系图
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph "API 端点"
|
|
API1[users.py]
|
|
API2[products.py]
|
|
end
|
|
|
|
subgraph "数据模式"
|
|
SCHEMA1[user schemas]
|
|
SCHEMA2[product schemas]
|
|
end
|
|
|
|
subgraph "业务服务"
|
|
SERVICE1[UserService]
|
|
SERVICE2[ProductService]
|
|
end
|
|
|
|
subgraph "数据库"
|
|
DB1[Database Models]
|
|
DB2[Database Connection]
|
|
end
|
|
|
|
API1 --> SCHEMA1
|
|
API1 --> SERVICE1
|
|
API2 --> SCHEMA2
|
|
API2 --> SERVICE2
|
|
|
|
SERVICE1 --> DB1
|
|
SERVICE1 --> DB2
|
|
SERVICE2 --> DB1
|
|
SERVICE2 --> DB2
|
|
|
|
SCHEMA1 --> DB1
|
|
SCHEMA2 --> DB1
|
|
```
|
|
|
|
## 接口契约定义
|
|
|
|
### Users API 接口
|
|
|
|
#### POST /api/v1/users/
|
|
```json
|
|
# Request
|
|
{
|
|
"username": "string",
|
|
"email": "string",
|
|
"full_name": "string"
|
|
}
|
|
|
|
# Response (201)
|
|
{
|
|
"id": 1,
|
|
"username": "string",
|
|
"email": "string",
|
|
"full_name": "string",
|
|
"is_active": true
|
|
}
|
|
|
|
# Error Response (422)
|
|
{
|
|
"detail": "User with email 'test@example.com' already exists"
|
|
}
|
|
```
|
|
|
|
#### PUT /api/v1/users/{user_id}
|
|
```json
|
|
# Request (部分更新)
|
|
{
|
|
"full_name": "string" // 可选字段
|
|
}
|
|
|
|
# Response (200)
|
|
{
|
|
"id": 1,
|
|
"username": "string",
|
|
"email": "string",
|
|
"full_name": "string",
|
|
"is_active": true
|
|
}
|
|
|
|
# Error Response (404)
|
|
{
|
|
"detail": "User not found"
|
|
}
|
|
```
|
|
|
|
#### DELETE /api/v1/users/{user_id}
|
|
```json
|
|
# Response (204) - No Content
|
|
|
|
# Error Response (404)
|
|
{
|
|
"detail": "User not found"
|
|
}
|
|
```
|
|
|
|
### Products API 接口
|
|
|
|
#### POST /api/v1/products/
|
|
```json
|
|
# Request
|
|
{
|
|
"name": "string",
|
|
"description": "string",
|
|
"price": 99.99,
|
|
"stock": 100
|
|
}
|
|
|
|
# Response (201)
|
|
{
|
|
"id": 1,
|
|
"name": "string",
|
|
"description": "string",
|
|
"price": 99.99,
|
|
"stock": 100,
|
|
"is_available": true
|
|
}
|
|
```
|
|
|
|
#### PUT /api/v1/products/{product_id}
|
|
```json
|
|
# Request (部分更新)
|
|
{
|
|
"price": 89.99,
|
|
"stock": 50
|
|
}
|
|
|
|
# Response (200)
|
|
{
|
|
"id": 1,
|
|
"name": "string",
|
|
"description": "string",
|
|
"price": 89.99,
|
|
"stock": 50,
|
|
"is_available": true
|
|
}
|
|
```
|
|
|
|
#### DELETE /api/v1/products/{product_id}
|
|
```json
|
|
# Response (204) - No Content
|
|
|
|
# Error Response (404)
|
|
{
|
|
"detail": "Product not found"
|
|
}
|
|
```
|
|
|
|
## 数据流向图
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant C as Client
|
|
participant API as API Router
|
|
participant V as Validator
|
|
participant S as Service
|
|
participant DB as Database
|
|
|
|
Note over C,DB: 创建用户流程
|
|
C->>API: POST /api/v1/users/
|
|
API->>V: 验证 UserCreate
|
|
V->>API: 验证通过
|
|
API->>S: UserService.create_user()
|
|
S->>DB: 检查邮箱唯一性
|
|
DB->>S: 邮箱可用
|
|
S->>DB: 创建用户记录
|
|
DB->>S: 返回创建的用户
|
|
S->>API: 返回 User 对象
|
|
API->>C: 201 + UserResponse
|
|
|
|
Note over C,DB: 更新用户流程
|
|
C->>API: PUT /api/v1/users/{id}
|
|
API->>V: 验证 UserUpdate
|
|
V->>API: 验证通过
|
|
API->>S: UserService.update_user()
|
|
S->>DB: 查找用户
|
|
DB->>S: 返回用户或 None
|
|
alt 用户存在
|
|
S->>DB: 更新用户信息
|
|
DB->>S: 返回更新的用户
|
|
S->>API: 返回 User 对象
|
|
API->>C: 200 + UserResponse
|
|
else 用户不存在
|
|
S->>API: 返回 None
|
|
API->>C: 404 Not Found
|
|
end
|
|
|
|
Note over C,DB: 删除用户流程
|
|
C->>API: DELETE /api/v1/users/{id}
|
|
API->>S: UserService.delete_user()
|
|
S->>DB: 查找并删除用户
|
|
DB->>S: 返回删除结果
|
|
alt 删除成功
|
|
S->>API: 返回 True
|
|
API->>C: 204 No Content
|
|
else 用户不存在
|
|
S->>API: 返回 False
|
|
API->>C: 404 Not Found
|
|
end
|
|
```
|
|
|
|
## 异常处理策略
|
|
|
|
### 分层异常处理
|
|
|
|
#### 1. API 层异常处理
|
|
- **HTTPException**: FastAPI 标准异常
|
|
- **状态码映射**: 业务异常转换为 HTTP 状态码
|
|
- **统一错误格式**: 结构化错误响应
|
|
|
|
#### 2. 服务层异常处理
|
|
- **业务异常**: 自定义异常类型
|
|
- **数据库异常**: SQLAlchemy 异常捕获和转换
|
|
- **验证异常**: Pydantic 验证错误处理
|
|
|
|
#### 3. 数据库层异常处理
|
|
- **连接异常**: 数据库连接失败处理
|
|
- **约束异常**: 唯一性约束、外键约束等
|
|
- **事务异常**: 事务回滚和重试机制
|
|
|
|
### 异常映射表
|
|
|
|
| 异常类型 | HTTP状态码 | 错误信息示例 |
|
|
|---------|-----------|-------------|
|
|
| 资源不存在 | 404 | "User not found" |
|
|
| 唯一性冲突 | 409 | "User with email already exists" |
|
|
| 数据验证失败 | 422 | "Invalid email format" |
|
|
| 数据库连接异常 | 500 | "Database connection error" |
|
|
| 未知异常 | 500 | "Internal server error" |
|
|
|
|
## 事务管理设计
|
|
|
|
### 数据库事务策略
|
|
```python
|
|
@staticmethod
|
|
def create_user(db: Session, user_data: UserCreate) -> User:
|
|
try:
|
|
# 业务逻辑操作
|
|
db_user = User(**user_data.model_dump())
|
|
db.add(db_user)
|
|
db.commit()
|
|
db.refresh(db_user)
|
|
return db_user
|
|
except IntegrityError as e:
|
|
db.rollback()
|
|
if "email" in str(e):
|
|
raise HTTPException(status_code=409, detail="Email already exists")
|
|
raise HTTPException(status_code=409, detail="Data conflict")
|
|
except Exception as e:
|
|
db.rollback()
|
|
raise HTTPException(status_code=500, detail="Internal server error")
|
|
```
|
|
|
|
### 会话生命周期
|
|
- **FastAPI 依赖注入**: 自动管理会话创建和关闭
|
|
- **异常安全**: 确保异常时会话正确回滚和关闭
|
|
- **连接池**: 复用现有连接池配置
|
|
|
|
## 性能考虑
|
|
|
|
### 数据库查询优化
|
|
- **索引使用**: 利用现有主键和唯一索引
|
|
- **查询优化**: 避免 N+1 查询问题
|
|
- **批量操作**: 必要时支持批量创建和更新
|
|
|
|
### 内存管理
|
|
- **会话管理**: 及时关闭数据库会话
|
|
- **对象生命周期**: 避免长期持有数据库对象引用
|
|
|
|
## 兼容性设计
|
|
|
|
### 向后兼容
|
|
- **现有 API**: 保持现有 GET API 不变
|
|
- **响应格式**: 保持现有响应结构
|
|
- **错误处理**: 保持现有错误处理风格
|
|
|
|
### 扩展性设计
|
|
- **服务接口**: 设计可扩展的服务接口
|
|
- **模式版本**: 支持模式版本演进
|
|
- **配置驱动**: 通过配置控制功能开关
|
|
|
|
---
|
|
|
|
**设计完成**: ✅ 架构设计完整
|
|
**创建时间**: 2025-09-28
|
|
**设计师**: Claude AI
|
|
**状态**: 准备进入原子化阶段 |