geo/.qoder/repowiki/zh/content/后端系统架构/API接口设计.md

455 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API接口设计
<cite>
**本文档引用的文件**
- [backend/app/main.py](file://backend/app/main.py)
- [backend/app/api/auth.py](file://backend/app/api/auth.py)
- [backend/app/api/queries.py](file://backend/app/api/queries.py)
- [backend/app/api/citations.py](file://backend/app/api/citations.py)
- [backend/app/api/reports.py](file://backend/app/api/reports.py)
- [backend/app/api/deps.py](file://backend/app/api/deps.py)
- [backend/app/schemas/auth.py](file://backend/app/schemas/auth.py)
- [backend/app/schemas/query.py](file://backend/app/schemas/query.py)
- [backend/app/schemas/citation.py](file://backend/app/schemas/citation.py)
- [backend/app/services/auth.py](file://backend/app/services/auth.py)
- [backend/app/services/query.py](file://backend/app/services/query.py)
- [backend/app/services/citation.py](file://backend/app/services/citation.py)
- [backend/app/database.py](file://backend/app/database.py)
- [backend/app/config.py](file://backend/app/config.py)
- [backend/app/models/user.py](file://backend/app/models/user.py)
- [backend/app/models/citation_record.py](file://backend/app/models/citation_record.py)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为 GEO 平台的 API 接口设计规范文档,面向后端与前端开发者,系统性阐述 RESTful API 设计原则、路由组织结构、版本控制策略、请求/响应数据模型Pydantic、错误处理机制、认证与授权、API 文档与测试策略,以及使用示例与最佳实践。
## 项目结构
后端采用 FastAPI 框架,按功能模块划分 API 路由与服务层,数据库使用 SQLAlchemy 异步引擎,配置通过 Pydantic Settings 管理。主要模块如下:
- 应用入口与路由注册backend/app/main.py
- 认证与用户backend/app/api/auth.py、backend/app/services/auth.py、backend/app/schemas/auth.py
- 查询词管理backend/app/api/queries.py、backend/app/services/query.py、backend/app/schemas/query.py
- 引用数据与统计backend/app/api/citations.py、backend/app/services/citation.py、backend/app/schemas/citation.py
- 报告导出backend/app/api/reports.py
- 依赖注入与鉴权backend/app/api/deps.py
- 数据库与模型backend/app/database.py、backend/app/models/*.py
- 配置backend/app/config.py
```mermaid
graph TB
A["应用入口<br/>backend/app/main.py"] --> B["认证路由<br/>backend/app/api/auth.py"]
A --> C["查询路由<br/>backend/app/api/queries.py"]
A --> D["引用路由<br/>backend/app/api/citations.py"]
A --> E["报告路由<br/>backend/app/api/reports.py"]
B --> F["认证服务<br/>backend/app/services/auth.py"]
C --> G["查询服务<br/>backend/app/services/query.py"]
D --> H["引用服务<br/>backend/app/services/citation.py"]
F --> I["数据库会话<br/>backend/app/database.py"]
G --> I
H --> I
I --> J["配置<br/>backend/app/config.py"]
I --> K["用户模型<br/>backend/app/models/user.py"]
I --> L["引用记录模型<br/>backend/app/models/citation_record.py"]
```
图表来源
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
- [backend/app/api/citations.py:1-78](file://backend/app/api/citations.py#L1-L78)
- [backend/app/api/reports.py:1-47](file://backend/app/api/reports.py#L1-L47)
- [backend/app/services/auth.py:1-69](file://backend/app/services/auth.py#L1-L69)
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
- [backend/app/services/citation.py:1-269](file://backend/app/services/citation.py#L1-L269)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)
章节来源
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
## 核心组件
- 版本控制与路由前缀
- 应用统一使用 /api/v1 前缀,并按资源划分子路由:
- /api/v1/auth认证相关
- /api/v1/queries查询词 CRUD
- /api/v1/citations引用数据列表、统计、立即执行
- /api/v1/reports报告导出
- CORS 配置
- 允许本地前端 localhost:3000 进行跨域访问,支持所有方法与头
- 健康检查
- GET /health 返回 {"status":"ok"}
章节来源
- [backend/app/main.py:24-48](file://backend/app/main.py#L24-L48)
## 架构总览
下图展示从客户端到 API、服务层与数据库的调用链路以及认证中间件如何注入当前用户上下文。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant API as "FastAPI 应用"
participant Router as "API 路由"
participant Deps as "依赖注入/鉴权"
participant Service as "业务服务"
participant DB as "数据库"
Client->>API : "HTTP 请求"
API->>Router : "路由分发"
Router->>Deps : "获取当前用户(鉴权)"
Deps-->>Router : "User 对象"
Router->>Service : "调用业务逻辑"
Service->>DB : "SQLAlchemy 异步查询/写入"
DB-->>Service : "结果集"
Service-->>Router : "领域对象/聚合"
Router-->>Client : "JSON 响应/状态码"
```
图表来源
- [backend/app/main.py:38-42](file://backend/app/main.py#L38-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/queries.py:15-85](file://backend/app/api/queries.py#L15-L85)
- [backend/app/api/citations.py:25-77](file://backend/app/api/citations.py#L25-L77)
- [backend/app/api/reports.py:16-46](file://backend/app/api/reports.py#L16-L46)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)
- [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29)
## 详细组件分析
### 认证与用户管理
- 路由与方法
- POST /api/v1/auth/register注册返回用户信息状态码 201
- POST /api/v1/auth/login登录返回访问令牌与用户信息状态码 200失败 401
- GET /api/v1/auth/me获取当前用户信息需携带 Bearer Token
- 鉴权流程
- 使用 OAuth2PasswordBearer 指向 /api/v1/auth/login
- 依赖 get_current_user 校验 JWT 并加载用户
- 数据模型
- 注册输入:邮箱、密码、姓名(最小长度约束)
- 登录输入:邮箱、密码
- 用户输出id、email、name、plan、max_queries、is_active、created_at
- 令牌输出access_token、token_type、user
- 错误处理
- 注册重复邮箱400
- 登录失败401带 WWW-Authenticate 头)
- 鉴权失败401凭据无效
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Auth as "认证路由"
participant Deps as "get_current_user"
participant Svc as "认证服务"
participant DB as "数据库"
Client->>Auth : "POST /api/v1/auth/login"
Auth->>Svc : "authenticate_user(email,password)"
Svc->>DB : "查询用户并校验密码"
DB-->>Svc : "用户对象"
Svc-->>Auth : "用户或None"
Auth-->>Client : "200 OK + {access_token,user}"
Note over Client,Auth : "后续请求携带 Authorization : Bearer <token>"
```
图表来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/services/auth.py:55-69](file://backend/app/services/auth.py#L55-L69)
章节来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/schemas/auth.py:7-34](file://backend/app/schemas/auth.py#L7-L34)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
### 查询词管理
- 路由与方法
- GET /api/v1/queries分页列出查询词支持 skip/limit
- POST /api/v1/queries创建查询词状态码 201
- GET /api/v1/queries/{query_id}:获取单个查询词
- PUT /api/v1/queries/{query_id}:更新查询词
- DELETE /api/v1/queries/{query_id}:删除查询词,状态码 204
- 输入/输出模型
- 创建输入keyword、target_brand、brand_aliases、platforms、frequency默认 weekly
- 更新输入:可选字段 keyword、target_brand、brand_aliases、platforms、frequency、status
- 输出:完整查询词详情(含频率、状态、时间戳等)
- 权限与限制
- 用户最大查询数受用户计划限制,超过抛出 403
- 所有操作均进行所有权校验user_id 匹配)
- 错误处理
- 未找到404
- 超出配额403
- 参数校验失败422Pydantic 自动)
```mermaid
flowchart TD
Start(["创建查询"]) --> CheckCount["检查用户当前查询数"]
CheckCount --> CountOK{"是否小于等于 max_queries?"}
CountOK -- 否 --> Forbidden["返回 403: 超出配额"]
CountOK -- 是 --> CalcNext["根据频率计算 next_query_at"]
CalcNext --> Create["持久化 Query 记录"]
Create --> Return201["返回 201 + QueryResponse"]
```
图表来源
- [backend/app/api/queries.py:26-39](file://backend/app/api/queries.py#L26-L39)
- [backend/app/services/query.py:45-81](file://backend/app/services/query.py#L45-L81)
章节来源
- [backend/app/api/queries.py:15-85](file://backend/app/api/queries.py#L15-L85)
- [backend/app/schemas/query.py:11-94](file://backend/app/schemas/query.py#L11-L94)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)
### 引用数据与统计
- 路由与方法
- GET /api/v1/citations分页列出引用记录支持 query_id、platform、日期范围过滤
- GET /api/v1/citations/stats统计摘要总查询、总引用、引用率、平台分布、趋势
- POST /api/v1/queries/{query_id}/run-now立即触发查询任务状态码 202
- 数据模型
- 引用记录输出id、query_id、platform、cited、citation_position、citation_text、competitor_brands、queried_at
- 统计输出:总览指标、平台维度统计、周粒度趋势
- 立即执行输出task_id、status、message
- 安全与权限
- 列表与统计均进行所有权校验;当提供 query_id 时额外校验查询归属
- 导出 CSV 亦进行所有权校验
- 错误处理
- 未找到查询404
- 查询非激活或无平台配置400/404
- 未授权/无效凭据401
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Cit as "引用路由"
participant Svc as "引用服务"
participant DB as "数据库"
Client->>Cit : "GET /api/v1/citations/stats?query_id={id}"
Cit->>Svc : "get_citation_stats(user_id, query_id?)"
Svc->>DB : "聚合统计(条件含 user_id 与可选 query_id)"
DB-->>Svc : "统计结果"
Svc-->>Cit : "CitationStatsResponse"
Cit-->>Client : "200 OK"
```
图表来源
- [backend/app/api/citations.py:49-56](file://backend/app/api/citations.py#L49-L56)
- [backend/app/services/citation.py:76-201](file://backend/app/services/citation.py#L76-L201)
章节来源
- [backend/app/api/citations.py:25-77](file://backend/app/api/citations.py#L25-L77)
- [backend/app/schemas/citation.py:7-50](file://backend/app/schemas/citation.py#L7-L50)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)
### 报告导出
- 路由与方法
- GET /api/v1/reports/export/csv导出 CSV 文件流,支持文件名与 Content-Disposition 头
- 错误处理
- 不支持的格式400
- 查询不存在404
- 流式响应StreamingResponse媒体类型 text/csv
章节来源
- [backend/app/api/reports.py:16-46](file://backend/app/api/reports.py#L16-L46)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
### 立即执行查询(独立路由)
- 路由与方法
- POST /api/v1/queries/{query_id}/run-now加入查询任务队列状态码 202
- 行为
- 校验查询归属与状态,为每个平台创建一个 QueryTask
- 错误处理
- 查询不存在或非激活404
- 无平台配置400
章节来源
- [backend/app/api/citations.py:59-77](file://backend/app/api/citations.py#L59-L77)
- [backend/app/services/citation.py:204-234](file://backend/app/services/citation.py#L204-L234)
## 依赖分析
- 组件耦合
- API 层仅依赖依赖注入与服务层,不直接操作数据库
- 服务层通过异步 Session 访问数据库,避免阻塞
- 配置集中于 Settings便于环境隔离
- 关键依赖关系
- OAuth2PasswordBearer 指向登录端点,确保令牌一致
- 所有受保护路由均通过 get_current_user 注入 User 上下文
- 业务服务内部进行所有权校验,保证数据隔离
```mermaid
graph LR
API_Auth["API 认证"] --> Deps["依赖注入"]
API_Queries["API 查询"] --> Deps
API_Citations["API 引用"] --> Deps
API_Reports["API 报告"] --> Deps
Deps --> Svc_Auth["认证服务"]
Deps --> Svc_Query["查询服务"]
Deps --> Svc_Citation["引用服务"]
Svc_Auth --> DB["数据库"]
Svc_Query --> DB
Svc_Citation --> DB
```
图表来源
- [backend/app/api/deps.py:13-43](file://backend/app/api/deps.py#L13-L43)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)
- [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29)
## 性能考虑
- 分页与过滤
- 列表接口支持 skip/limit建议前端按需请求避免一次性拉取大量数据
- 引用列表支持多维过滤query_id、platform、日期建议在高频查询场景下配合索引
- 数据库索引
- 引用记录表对 query_id、queried_at、platform 建有索引,有利于统计与分页
- 异步 I/O
- 使用 SQLAlchemy 异步引擎与异步 Session减少阻塞
- 缓存与队列
- 立即执行查询通过任务队列异步处理,避免长耗时请求阻塞 API
## 故障排查指南
- 401 未授权
- 检查 Authorization 头是否为 Bearer Token
- 检查 token 是否过期或签名错误
- 403 禁止访问
- 用户配额不足或权限不足(如创建查询超限)
- 404 未找到
- 资源 ID 不存在或不属于当前用户
- 400 参数错误
- 平台列表为空或包含非法值;导出格式不支持
- 500 服务器错误
- 检查数据库连接与服务日志
章节来源
- [backend/app/api/auth.py:26-30](file://backend/app/api/auth.py#L26-L30)
- [backend/app/api/queries.py:34-38](file://backend/app/api/queries.py#L34-L38)
- [backend/app/api/citations.py:67-71](file://backend/app/api/citations.py#L67-L71)
- [backend/app/api/reports.py:23-27](file://backend/app/api/reports.py#L23-L27)
- [backend/app/api/deps.py:20-41](file://backend/app/api/deps.py#L20-L41)
## 结论
本规范以 RESTful 设计为核心,结合 FastAPI 的类型安全与自动文档能力,构建了清晰的路由分层、严格的认证授权与完善的错误处理机制。通过 Pydantic 模型与 SQLAlchemy 异步 ORM实现了高一致性与高性能的数据访问。建议在生产环境中进一步完善速率限制、审计日志与监控告警体系。
## 附录
### RESTful 设计原则与路由组织
- URL 命名规范
- 使用名词复数形式表示资源集合,如 /queries、/citations
- 资源标识符使用路径参数,如 /queries/{query_id}
- HTTP 方法使用
- GET读取资源列表或单个资源
- POST创建资源
- PUT更新资源
- DELETE删除资源
- 状态码标准
- 200成功获取或更新
- 201创建成功
- 202异步任务已接受
- 204删除成功且无内容
- 400参数或业务错误
- 401未授权
- 403禁止访问
- 404资源不存在
- 422数据校验失败Pydantic
- 500服务器内部错误
### API 版本控制与路由前缀
- 版本控制策略
- 采用 URL 前缀 /api/v1 进行版本隔离,便于未来演进
- 路由前缀管理
- 认证:/api/v1/auth
- 查询词:/api/v1/queries
- 引用数据:/api/v1/citations
- 报告:/api/v1/reports
章节来源
- [backend/app/main.py:38-42](file://backend/app/main.py#L38-L42)
### 请求与响应数据模型Pydantic
- 认证
- 注册输入:邮箱、密码、姓名(最小长度约束)
- 登录输入:邮箱、密码
- 用户输出id、email、name、plan、max_queries、is_active、created_at
- 令牌输出access_token、token_type、user
- 查询词
- 创建输入keyword、target_brand、brand_aliases、platforms、frequency默认 weekly
- 更新输入:可选字段 keyword、target_brand、brand_aliases、platforms、frequency、status
- 输出:完整查询词详情(含频率、状态、时间戳等)
- 引用数据
- 列表项id、query_id、platform、cited、citation_position、citation_text、competitor_brands、queried_at
- 统计:总览指标、平台维度统计、周粒度趋势
- 立即执行task_id、status、message
章节来源
- [backend/app/schemas/auth.py:7-34](file://backend/app/schemas/auth.py#L7-L34)
- [backend/app/schemas/query.py:11-94](file://backend/app/schemas/query.py#L11-L94)
- [backend/app/schemas/citation.py:7-50](file://backend/app/schemas/citation.py#L7-L50)
### 错误处理机制
- 异常类型分类
- 业务异常:如配额不足、查询不存在、平台非法
- 凭据异常JWT 解析失败、用户不存在
- 错误响应格式
- 统一为 JSON{ "detail": "错误描述" }
- 未授权携带 WWW-Authenticate 头
- HTTP 状态码映射
- 400参数/业务错误
- 401凭据无效
- 403权限不足
- 404资源不存在
- 422数据校验失败
- 500服务器错误
章节来源
- [backend/app/api/auth.py:17-18](file://backend/app/api/auth.py#L17-L18)
- [backend/app/api/queries.py:34-38](file://backend/app/api/queries.py#L34-L38)
- [backend/app/api/citations.py:67-71](file://backend/app/api/citations.py#L67-L71)
- [backend/app/api/reports.py:23-27](file://backend/app/api/reports.py#L23-L27)
- [backend/app/api/deps.py:20-41](file://backend/app/api/deps.py#L20-L41)
### 认证与授权实现
- 认证方式
- JWT Bearer Token密钥与过期时间由配置管理
- 授权策略
- 所有受保护路由通过 get_current_user 注入当前用户
- 业务层进行所有权校验user_id 匹配),防止越权访问
- 最佳实践
- 生产环境更换默认密钥与设置合理过期时间
- 前端统一在请求头携带 Authorization: Bearer <token>
章节来源
- [backend/app/api/deps.py:13-43](file://backend/app/api/deps.py#L13-L43)
- [backend/app/services/auth.py:24-34](file://backend/app/services/auth.py#L24-L34)
- [backend/app/config.py:9-10](file://backend/app/config.py#L9-L10)
### API 文档生成与测试策略
- 文档生成
- FastAPI 自动生成 OpenAPI 规范与交互式文档,默认启用
- 测试策略
- 单元测试:针对服务层函数(如 get_citations、create_query进行异步测试
- 集成测试:通过 API 路由层发起请求,验证鉴权、权限与错误码
- 建议使用 pytest 异步运行器与测试数据库
### API 使用示例与最佳实践
- 示例
- 登录获取令牌后,在后续请求头中添加 Authorization: Bearer <token>
- 创建查询时指定 platforms 与 frequency注意平台集合的有效性
- 导出报告时仅支持 csv 格式
- 最佳实践
- 前端分页请求 skip/limit避免一次性加载过多数据
- 在高频查询场景下利用过滤参数缩小数据集
- 对外暴露的路由保持幂等性与明确的状态码语义