# 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,避免一次性加载过多数据 - 在高频查询场景下利用过滤参数缩小数据集 - 对外暴露的路由保持幂等性与明确的状态码语义