Files
par/docs/mediabot-api-migration.md
mediabot-pt c823878ae0 fix: 解决 ConfigServiceImpl 与 SiteSnapshotServiceImpl 循环依赖
- 移除 SiteSnapshotServiceImpl 对 ConfigService 的依赖,直接使用 SiteConfigMapper
- ConfigServiceImpl/SitePagesServiceImpl/RiskRuleServiceImpl 改用 ApplicationEvent 异步触发快照更新
- 新增 SnapshotUpdateEvent 和 SnapshotUpdateListener
- ParApplication 添加 @EnableAsync 支持异步事件处理
- AdminController 中 updateSnapshot 调用改为发布事件
2026-07-07 11:17:22 +08:00

274 lines
8.5 KiB
Markdown
Raw 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.

# PAR Server 接口升级对比文档 (供 MediaBot 迁移)
> **版本**: V2.0(SiteSnapshot 重构)
> **日期**: 2026-07-07
> **面向对象**: MediaBot 开发团队
---
## 一、升级概览
本次重构将站点配置的存储和分发方式从 **"分散存储 + 运行时合并"** 升级为 **"统一快照 + 增量更新"**。核心变化:
| 维度 | 旧方案 (V1) | 新方案 (V2) |
|------|------------|------------|
| **存储** | 脚本/页面/规则分别存七牛云 | MySQL `site_snapshots` 表统一存储 + 七牛云 CDN 灾备 |
| **获取方式** | 多次请求分别获取脚本、页面、规则 | **一次请求获取完整 bundle** |
| **更新检测** | 无/各接口各自判断 | **统一 checksum + ETag/304** 增量更新 |
| **可用性** | 依赖七牛云 | 数据库为主 + 七牛云 CDN 自动灾备 |
---
## 二、新增接口(推荐 MediaBot 迁移到这些)
### 2.1 `GET /api/v1/snapshots/{siteId}` ⭐ 推荐
**用途**: 获取站点完整配置快照(一站式获取脚本 + 页面配置 + 风险规则)
**请求头**:
```
If-None-Match: {上次返回的 ETag checksum}
```
**响应 200 OK**(内容未变化时):
```json
{
"siteId": "example.com",
"generatedAt": "2026-07-07T10:30:00",
"script": "// Groovy 脚本完整源码...",
"scriptVersion": "3",
"scriptSource": "custom",
"pages": [
{
"pageKey": "INDEX",
"url": "https://example.com/torrents.php",
"method": "GET",
"...": "..."
}
],
"pagesVersion": "2",
"pagesSource": "custom",
"riskRules": [
{
"field": "title",
"operator": "contains",
"value": "xxx",
"level": "WARN"
}
],
"riskRulesVersion": 1
}
```
**响应 304 Not Modified**(内容未变化):
```
HTTP/1.1 304 Not Modified
ETag: "abc123def456..."
```
_(Body 为空,节省带宽)_
**可用性保障**:
- 优先从 MySQL 数据库读取
- 数据库不可用时自动回退到七牛云 CDN `snapshots/{siteId}.json`
- 两层级联失败返回 500
---
### 2.2 `GET /api/v1/snapshots/{siteId}/check` ⭐ 推荐
**用途**: 轻量级检查站点是否有配置更新(不传输配置内容)
**响应**:
```json
{
"code": 200,
"data": {
"checksum": "abc123def456...",
"version": 5,
"publishedAt": "2026-07-07T10:30:00"
}
}
```
**使用模式**:
1. MediaBot 先调 `/check` 获取最新 `checksum`
2. 与本地缓存的 checksum 比较
3. 不同时再调 `/snapshots/{siteId}` 拉取完整配置
---
## 三、旧接口兼容状态
以下接口**继续可用**,但推荐逐步迁移到新接口:
### 3.1 `GET /api/v1/configs/{siteId}/bundle` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 继续可用,底层已委托给快照服务 |
| **变化** | 无破坏性变化,响应格式不变 |
| **建议** | 可继续使用,但建议迁移到 `GET /api/v1/snapshots/{siteId}` |
**数据流变化**:
```
旧: 七牛云 bundles/{siteId}.json → 返回
新: MySQL site_snapshots → 返回 (优先)
↓ 失败
七牛云 bundles/{siteId}.json / snapshots/{siteId}.json → 返回 (回退)
↓ 失败
实时构建 → 返回 (兜底)
```
### 3.2 `GET /api/v1/configs/{siteId}/script` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化,功能一致 |
| **建议** | 如需单独获取脚本,可继续使用;否则建议用 snapshot 一次性获取 |
### 3.3 `GET /api/v1/scripts/{siteId}` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化,功能一致 |
| **说明** | 仅返回 Groovy 脚本纯文本,无 JSON 包装 |
| **建议** | 如需单独获取脚本,可继续使用 |
### 3.4 `GET /api/v1/scripts/{siteId}/version` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化 |
| **响应** | `{ "version": "3", "source": "custom" }` |
| **建议** | 可用 `/snapshots/{siteId}/check` 替代,后者提供更全面的版本信息 |
### 3.5 `GET /api/v1/manifest` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化,仍支持 ETag |
| **说明** | 返回所有活跃站点配置索引(siteId、站点类型、是否有脚本/页面/规则等元信息) |
| **建议** | 继续用于获取全量站点列表和配置状态概览 |
### 3.6 `GET /api/v1/sites/{siteId}/pages` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化 |
| **建议** | 如只需页面配置,可继续使用;否则建议用 snapshot |
### 3.7 `GET /api/v1/risk-rules/{siteType}` — ⚠️ 保持兼容
| 项目 | 说明 |
|------|------|
| **状态** | 无变化,仍支持版本号增量判断 |
| **建议** | 如只需风险规则,可继续使用;否则建议用 snapshot |
---
## 四、推荐 MediaBot 迁移方案
### 方案 A:完全迁移到 Snapshot(推荐)
```
MediaBot 启动 / 定时任务:
1. GET /api/v1/manifest → 获取全量站点列表
2. 对每个站点:
a. GET /api/v1/snapshots/{siteId}/check → 获取最新 checksum
b. 与本地缓存的 checksum 比较
c. 不同时: GET /api/v1/snapshots/{siteId} → 拉取完整 bundle
d. 缓存 checksum 和完整 bundle
```
**优点**:
- 每次只需 1~2 次 HTTP 请求即可获取站点全部配置
- ETag/304 支持,配置未变时不传输内容
- 三层可用性保障(数据库 → CDN → 实时构建)
### 方案 B:渐进式迁移(兼容期)
```
1. 优先调用新接口 GET /api/v1/snapshots/{siteId}
2. 失败时 fallback 到旧接口组合:
- GET /api/v1/configs/{siteId}/script
- GET /api/v1/sites/{siteId}/pages
- GET /api/v1/risk-rules/{siteType}
```
---
## 五、响应格式对比
### 旧方式(分散获取)
需要 **3~4 次 HTTP 请求** 才能凑齐一个站点的完整配置:
```
请求 1: GET /api/v1/configs/{siteId}/script → 返回 Groovy 脚本纯文本
请求 2: GET /api/v1/sites/{siteId}/pages → 返回页面入口配置
请求 3: GET /api/v1/risk-rules/{siteType} → 返回风险规则
请求 4: (可选) GET /api/v1/manifest → 返回全局站点列表
```
### 新方式(统一快照)
**1~2 次 HTTP 请求** 获取站点完整配置:
```
请求 1: GET /api/v1/snapshots/{siteId} (带 If-None-Match) → 返回完整 bundle
- 配置未变化: 304 Not Modified (0 流量)
- 配置有变化: 200 OK + 完整 JSON
(可选) 请求 0: GET /api/v1/manifest → 获取全量站点列表
```
### Bundle JSON 响应字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `siteId` | string | 站点标识 |
| `generatedAt` | string | 快照生成时间 (ISO 8601) |
| `script` | string | Groovy 脚本完整源码 |
| `scriptVersion` | string | 脚本版本号 |
| `scriptSource` | string | `"custom"` 或 `"default"` |
| `pages` | array | 页面入口配置条目列表 |
| `pagesVersion` | string | 页面配置版本号 |
| `pagesSource` | string | `"custom"` 或 `"default"` |
| `riskRules` | array | 风险规则列表 |
| `riskRulesVersion` | integer | 风险规则版本号 |
---
## 六、鉴权说明
**无变化**。所有配置读取接口(snapshot、manifest、script、pages、risk-rules)均为**公开接口**,无需鉴权。提交类接口需 HMAC/PSK 或 JWT 认证。
---
## 七、迁移时间线建议
| 阶段 | 时间 | 操作 |
|------|------|------|
| **Phase 1** | 立即 | MediaBot 开始调用 `/snapshots/{siteId}` 作为主路径,旧接口作为 fallback |
| **Phase 2** | 稳定运行 2 周后 | 移除旧接口 fallback 逻辑 |
| **Phase 3** | 后续版本 | 视情况废弃分散获取接口(script/pages/rules 独立端点) |
---
## 八、FAQ
**Q: 旧接口会下线吗?**
A: 短期内不会。但建议尽快迁移到 snapshot 接口以获得更好的性能和可用性。
**Q: snapshot 接口响应时间会不会更长?**
A: 不会。数据库查询是单次 SQL(按 site_id + status 索引),且应用层有 Caffeine 缓存。304 场景下完全不传输内容。
**Q: 如果 PAR Server 完全挂了怎么办?**
A: Snapshot 在发布时会同步上传到七牛云 CDN (`snapshots/{siteId}.json`),MediaBot 可以直接从 CDN 读取作为终极灾备。
**Q: checksum 是用什么算法计算的?**
A: SHA-256,对完整 bundle JSON 内容计算。
**Q: bundle 和 snapshot 的区别?**
A: 同一份数据。`/configs/{siteId}/bundle` 是兼容旧路径,`/snapshots/{siteId}` 是新路径,底层数据源相同。