# API接口设计
**本文档引用的文件**
- [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)
## 目录
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["应用入口
backend/app/main.py"] --> B["认证路由
backend/app/api/auth.py"]
A --> C["查询路由
backend/app/api/queries.py"]
A --> D["引用路由
backend/app/api/citations.py"]
A --> E["报告路由
backend/app/api/reports.py"]
B --> F["认证服务
backend/app/services/auth.py"]
C --> G["查询服务
backend/app/services/query.py"]
D --> H["引用服务
backend/app/services/citation.py"]
F --> I["数据库会话
backend/app/database.py"]
G --> I
H --> I
I --> J["配置
backend/app/config.py"]
I --> K["用户模型
backend/app/models/user.py"]
I --> L["引用记录模型
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 "
```
图表来源
- [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
- 参数校验失败:422(Pydantic 自动)
```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
章节来源
- [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
- 创建查询时指定 platforms 与 frequency,注意平台集合的有效性
- 导出报告时仅支持 csv 格式
- 最佳实践
- 前端分页请求 skip/limit,避免一次性加载过多数据
- 在高频查询场景下利用过滤参数缩小数据集
- 对外暴露的路由保持幂等性与明确的状态码语义