20 KiB
20 KiB
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)目录
简介
本文件为 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
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
- backend/app/api/auth.py:1-43
- backend/app/api/queries.py:1-86
- backend/app/api/citations.py:1-78
- backend/app/api/reports.py:1-47
- backend/app/services/auth.py:1-69
- backend/app/services/query.py:1-130
- backend/app/services/citation.py:1-269
- backend/app/database.py:1-29
- backend/app/config.py:1-17
- backend/app/models/user.py:1-41
- backend/app/models/citation_record.py:1-42
章节来源
核心组件
- 版本控制与路由前缀
- 应用统一使用 /api/v1 前缀,并按资源划分子路由:
- /api/v1/auth:认证相关
- /api/v1/queries:查询词 CRUD
- /api/v1/citations:引用数据列表、统计、立即执行
- /api/v1/reports:报告导出
- 应用统一使用 /api/v1 前缀,并按资源划分子路由:
- CORS 配置
- 允许本地前端 localhost:3000 进行跨域访问,支持所有方法与头
- 健康检查
- GET /health 返回 {"status":"ok"}
章节来源
架构总览
下图展示从客户端到 API、服务层与数据库的调用链路,以及认证中间件如何注入当前用户上下文。
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
- backend/app/api/deps.py:16-43
- backend/app/api/auth.py:13-42
- backend/app/api/queries.py:15-85
- backend/app/api/citations.py:25-77
- backend/app/api/reports.py:16-46
- backend/app/services/auth.py:37-69
- backend/app/services/query.py:12-130
- backend/app/services/citation.py:24-269
- backend/app/database.py:23-29
详细组件分析
认证与用户管理
- 路由与方法
- 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(凭据无效)
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
- backend/app/api/deps.py:16-43
- backend/app/schemas/auth.py:7-34
- backend/app/services/auth.py:37-69
查询词管理
- 路由与方法
- 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 自动)
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:15-85
- backend/app/schemas/query.py:11-94
- backend/app/services/query.py:12-130
引用数据与统计
- 路由与方法
- 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
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:25-77
- backend/app/schemas/citation.py:7-50
- backend/app/services/citation.py:24-269
报告导出
- 路由与方法
- GET /api/v1/reports/export/csv:导出 CSV 文件流,支持文件名与 Content-Disposition 头
- 错误处理
- 不支持的格式:400
- 查询不存在:404
- 流式响应:StreamingResponse,媒体类型 text/csv
章节来源
立即执行查询(独立路由)
- 路由与方法
- POST /api/v1/queries/{query_id}/run-now:加入查询任务队列,状态码 202
- 行为
- 校验查询归属与状态,为每个平台创建一个 QueryTask
- 错误处理
- 查询不存在或非激活:404
- 无平台配置:400
章节来源
依赖分析
- 组件耦合
- API 层仅依赖依赖注入与服务层,不直接操作数据库
- 服务层通过异步 Session 访问数据库,避免阻塞
- 配置集中于 Settings,便于环境隔离
- 关键依赖关系
- OAuth2PasswordBearer 指向登录端点,确保令牌一致
- 所有受保护路由均通过 get_current_user 注入 User 上下文
- 业务服务内部进行所有权校验,保证数据隔离
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
- backend/app/services/auth.py:37-69
- backend/app/services/query.py:12-130
- backend/app/services/citation.py:24-269
- backend/app/database.py:23-29
性能考虑
- 分页与过滤
- 列表接口支持 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
- backend/app/api/queries.py:34-38
- backend/app/api/citations.py:67-71
- backend/app/api/reports.py:23-27
- backend/app/api/deps.py:20-41
结论
本规范以 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
章节来源
请求与响应数据模型(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
- backend/app/schemas/query.py:11-94
- backend/app/schemas/citation.py:7-50
错误处理机制
- 异常类型分类
- 业务异常:如配额不足、查询不存在、平台非法
- 凭据异常:JWT 解析失败、用户不存在
- 错误响应格式
- 统一为 JSON:{ "detail": "错误描述" }
- 未授权携带 WWW-Authenticate 头
- HTTP 状态码映射
- 400:参数/业务错误
- 401:凭据无效
- 403:权限不足
- 404:资源不存在
- 422:数据校验失败
- 500:服务器错误
章节来源
- backend/app/api/auth.py:17-18
- backend/app/api/queries.py:34-38
- backend/app/api/citations.py:67-71
- backend/app/api/reports.py:23-27
- backend/app/api/deps.py:20-41
认证与授权实现
- 认证方式
- JWT Bearer Token,密钥与过期时间由配置管理
- 授权策略
- 所有受保护路由通过 get_current_user 注入当前用户
- 业务层进行所有权校验(user_id 匹配),防止越权访问
- 最佳实践
- 生产环境更换默认密钥与设置合理过期时间
- 前端统一在请求头携带 Authorization: Bearer
章节来源
API 文档生成与测试策略
- 文档生成
- FastAPI 自动生成 OpenAPI 规范与交互式文档,默认启用
- 测试策略
- 单元测试:针对服务层函数(如 get_citations、create_query)进行异步测试
- 集成测试:通过 API 路由层发起请求,验证鉴权、权限与错误码
- 建议使用 pytest 异步运行器与测试数据库
API 使用示例与最佳实践
- 示例
- 登录获取令牌后,在后续请求头中添加 Authorization: Bearer
- 创建查询时指定 platforms 与 frequency,注意平台集合的有效性
- 导出报告时仅支持 csv 格式
- 最佳实践
- 前端分页请求 skip/limit,避免一次性加载过多数据
- 在高频查询场景下利用过滤参数缩小数据集
- 对外暴露的路由保持幂等性与明确的状态码语义