6152d49d18
- CODING-STANDARD.md: PEP 8, type hints, Clean Architecture constraints, security - API-SPEC.md: RESTful design, HTTP methods, status codes, request/response format - TESTING-GUIDE.md: test strategy, AAA pattern, fixtures, coverage targets - complete examples included
376 lines
6.1 KiB
Markdown
376 lines
6.1 KiB
Markdown
# API 规范
|
||
|
||
本文档定义新 SaaS 项目的 REST API 设计规范。
|
||
|
||
---
|
||
|
||
## 1. 基本原则
|
||
|
||
- **RESTful** 设计
|
||
- **JSON** 数据格式
|
||
- **HTTP 状态码** 语义化
|
||
- **版本化** API(未来)
|
||
- **文档化** (Swagger/ReDoc)
|
||
|
||
---
|
||
|
||
## 2. URL 设计
|
||
|
||
### 2.1 资源命名
|
||
|
||
**使用复数名词**:
|
||
```
|
||
✅ /api/projects
|
||
✅ /api/asset-libraries
|
||
✅ /api/assets
|
||
✅ /api/ingest-jobs
|
||
|
||
❌ /api/project
|
||
❌ /api/assetLibrary
|
||
❌ /api/get_assets
|
||
```
|
||
|
||
**使用 kebab-case**:
|
||
```
|
||
✅ /api/asset-libraries
|
||
✅ /api/ingest-jobs
|
||
|
||
❌ /api/assetLibraries
|
||
❌ /api/ingest_jobs
|
||
```
|
||
|
||
### 2.2 路径层级
|
||
|
||
**浅层级**(推荐):
|
||
```
|
||
✅ GET /api/projects?workspace_id=ws-1
|
||
✅ GET /api/assets?library_id=lib-1
|
||
|
||
❌ GET /api/workspaces/ws-1/projects
|
||
❌ GET /api/projects/proj-1/libraries/lib-1/assets
|
||
```
|
||
|
||
**原因**:
|
||
- 避免深层嵌套
|
||
- 查询参数更灵活
|
||
- URL 更简洁
|
||
|
||
---
|
||
|
||
## 3. HTTP 方法
|
||
|
||
| 方法 | 用途 | 幂等性 | 安全性 |
|
||
|------|------|--------|--------|
|
||
| GET | 查询资源 | ✅ | ✅ |
|
||
| POST | 创建资源 | ❌ | ❌ |
|
||
| PUT | 完整更新 | ✅ | ❌ |
|
||
| PATCH | 部分更新 | ❌ | ❌ |
|
||
| DELETE | 删除资源 | ✅ | ❌ |
|
||
|
||
### 3.1 示例
|
||
|
||
```http
|
||
# 查询项目列表
|
||
GET /api/projects?workspace_id=ws-1
|
||
|
||
# 创建项目
|
||
POST /api/projects
|
||
Content-Type: application/json
|
||
{
|
||
"workspace_id": "ws-1",
|
||
"name": "新项目",
|
||
"description": "描述"
|
||
}
|
||
|
||
# 更新项目
|
||
PUT /api/projects/{project_id}
|
||
Content-Type: application/json
|
||
{
|
||
"name": "更新后的名称",
|
||
"description": "更新后的描述"
|
||
}
|
||
|
||
# 删除项目
|
||
DELETE /api/projects/{project_id}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. HTTP 状态码
|
||
|
||
### 4.1 成功响应
|
||
|
||
| 状态码 | 含义 | 使用场景 |
|
||
|--------|------|----------|
|
||
| 200 OK | 成功 | GET、PUT、PATCH |
|
||
| 201 Created | 创建成功 | POST |
|
||
| 204 No Content | 成功无内容 | DELETE |
|
||
|
||
### 4.2 客户端错误
|
||
|
||
| 状态码 | 含义 | 使用场景 |
|
||
|--------|------|----------|
|
||
| 400 Bad Request | 请求参数错误 | 参数验证失败 |
|
||
| 401 Unauthorized | 未认证 | 缺少 token |
|
||
| 403 Forbidden | 无权限 | 权限不足 |
|
||
| 404 Not Found | 资源不存在 | 资源未找到 |
|
||
| 409 Conflict | 冲突 | 资源已存在 |
|
||
| 422 Unprocessable Entity | 业务逻辑错误 | 业务规则违反 |
|
||
|
||
### 4.3 服务器错误
|
||
|
||
| 状态码 | 含义 | 使用场景 |
|
||
|--------|------|----------|
|
||
| 500 Internal Server Error | 服务器错误 | 未预期的异常 |
|
||
| 503 Service Unavailable | 服务不可用 | 维护中 |
|
||
|
||
---
|
||
|
||
## 5. 请求格式
|
||
|
||
### 5.1 查询参数(GET)
|
||
|
||
```http
|
||
GET /api/projects?workspace_id=ws-1&page=1&page_size=20
|
||
```
|
||
|
||
**命名**:snake_case
|
||
|
||
**分页参数**:
|
||
- `page` - 页码(从 1 开始)
|
||
- `page_size` - 每页数量(默认 20,最大 100)
|
||
|
||
**过滤参数**:
|
||
- `workspace_id` - 按工作空间过滤
|
||
- `kind` - 按类型过滤
|
||
- `status` - 按状态过滤
|
||
|
||
**排序参数**:
|
||
- `sort_by` - 排序字段(如 `created_at`)
|
||
- `sort_order` - 排序方向(`asc` / `desc`)
|
||
|
||
### 5.2 请求体(POST/PUT/PATCH)
|
||
|
||
```json
|
||
{
|
||
"workspace_id": "ws-1",
|
||
"name": "项目名称",
|
||
"description": "项目描述"
|
||
}
|
||
```
|
||
|
||
**命名**:snake_case
|
||
|
||
---
|
||
|
||
## 6. 响应格式
|
||
|
||
### 6.1 单个资源
|
||
|
||
```json
|
||
{
|
||
"id": "proj-123",
|
||
"workspace_id": "ws-1",
|
||
"name": "项目名称",
|
||
"description": "项目描述",
|
||
"created_at": "2026-06-15T08:00:00Z"
|
||
}
|
||
```
|
||
|
||
### 6.2 资源列表
|
||
|
||
```json
|
||
{
|
||
"items": [
|
||
{
|
||
"id": "proj-123",
|
||
"workspace_id": "ws-1",
|
||
"name": "项目 1"
|
||
},
|
||
{
|
||
"id": "proj-456",
|
||
"workspace_id": "ws-1",
|
||
"name": "项目 2"
|
||
}
|
||
],
|
||
"total": 42,
|
||
"page": 1,
|
||
"page_size": 20
|
||
}
|
||
```
|
||
|
||
### 6.3 错误响应
|
||
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": "VALIDATION_ERROR",
|
||
"message": "项目名称不能为空",
|
||
"details": {
|
||
"field": "name",
|
||
"value": ""
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误码**:
|
||
- `VALIDATION_ERROR` - 参数验证失败
|
||
- `NOT_FOUND` - 资源不存在
|
||
- `CONFLICT` - 资源冲突
|
||
- `PERMISSION_DENIED` - 权限不足
|
||
- `INTERNAL_ERROR` - 服务器错误
|
||
|
||
---
|
||
|
||
## 7. 认证与授权
|
||
|
||
### 7.1 认证(Phase 2)
|
||
|
||
```http
|
||
GET /api/projects
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
### 7.2 授权(Phase 3)
|
||
|
||
```http
|
||
GET /api/projects/{project_id}
|
||
Authorization: Bearer {token}
|
||
X-Workspace-ID: ws-1
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 版本化(Phase 3)
|
||
|
||
```http
|
||
GET /api/v1/projects
|
||
GET /api/v2/projects
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 接口示例
|
||
|
||
### 9.1 项目管理
|
||
|
||
**创建项目**:
|
||
```http
|
||
POST /api/projects
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"workspace_id": "ws-1",
|
||
"name": "新项目",
|
||
"description": "描述"
|
||
}
|
||
|
||
Response 201:
|
||
{
|
||
"id": "proj-123",
|
||
"workspace_id": "ws-1",
|
||
"name": "新项目",
|
||
"description": "描述",
|
||
"created_at": "2026-06-15T08:00:00Z"
|
||
}
|
||
```
|
||
|
||
**查询项目列表**:
|
||
```http
|
||
GET /api/projects?workspace_id=ws-1&page=1&page_size=20
|
||
|
||
Response 200:
|
||
{
|
||
"items": [...],
|
||
"total": 42,
|
||
"page": 1,
|
||
"page_size": 20
|
||
}
|
||
```
|
||
|
||
### 9.2 素材上传
|
||
|
||
**上传素材**:
|
||
```http
|
||
POST /api/upload
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"workspace_id": "ws-1",
|
||
"project_id": "proj-1",
|
||
"library_id": "lib-1",
|
||
"filename": "video.mp4"
|
||
}
|
||
|
||
Response 201:
|
||
{
|
||
"storage_key": "uploads/abc123/video.mp4",
|
||
"ingest_job_id": "job-456"
|
||
}
|
||
```
|
||
|
||
### 9.3 任务查询
|
||
|
||
**查询入库任务**:
|
||
```http
|
||
GET /api/ingest-jobs/{job_id}
|
||
|
||
Response 200:
|
||
{
|
||
"id": "job-456",
|
||
"workspace_id": "ws-1",
|
||
"project_id": "proj-1",
|
||
"library_id": "lib-1",
|
||
"storage_key": "uploads/abc123/video.mp4",
|
||
"status": "completed",
|
||
"result_asset_id": "asset-789",
|
||
"created_at": "2026-06-15T08:00:00Z",
|
||
"updated_at": "2026-06-15T08:01:00Z"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 性能优化
|
||
|
||
### 10.1 分页
|
||
|
||
**强制分页**(避免返回大量数据):
|
||
```http
|
||
GET /api/assets?library_id=lib-1&page=1&page_size=20
|
||
```
|
||
|
||
### 10.2 字段过滤(Phase 2)
|
||
|
||
```http
|
||
GET /api/projects?fields=id,name
|
||
```
|
||
|
||
### 10.3 批量操作(Phase 2)
|
||
|
||
```http
|
||
POST /api/assets/batch
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"operations": [
|
||
{"action": "delete", "id": "asset-1"},
|
||
{"action": "delete", "id": "asset-2"}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 文档化
|
||
|
||
使用 **FastAPI** 自动生成文档:
|
||
- Swagger UI: `http://localhost:8000/docs`
|
||
- ReDoc: `http://localhost:8000/redoc`
|
||
|
||
---
|
||
|
||
**最后更新**: 2026-06-15
|
||
**版本**: v1.0
|