Files
par/docs/mediabot-api-migration.md

328 lines
11 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.

# 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}` ⭐ 推荐
**用途**: 获取站点完整配置快照(一站式获取脚本 + 页面配置 + 风险规则)
**查询参数**:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `preview` | boolean | `false` | `false`=仅正式版(published),`true`=预览版优先(draft → published fallback) |
**请求头**:
```
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 为空,节省带宽)_
**可用性保障**(PAR Server 端三层级联):
- 第一层:优先从 MySQL 数据库读取
- 第二层:数据库异常时自动回退到七牛云 CDN `snapshots/{siteId}.json`
- 第三层:CDN 也无数据时,实时构建(从各子表 + 七牛云存储拼装)
- 全部失败返回 500
**MediaBot 端建议**(应对 PAR Server 整体不可用):
- MediaBot 应缓存每个站点的 CDN URL(`https://{七牛云CDN域名}/snapshots/{siteId}.json`)
- 当 PAR Server 连接超时/拒绝连接时,直接请求 CDN URL 作为终极 fallback
- 这样即使 PAR Server 宕机,配置仍可通过 CDN 获取(每次 publish 都会同步上传到 CDN)
---
### 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. PAR Server 不可用时 fallback 到 CDN:
- 直接 GET https://{CDN域名}/snapshots/{siteId}.json
3. CDN 也无数据时 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 | 站点标识 |
| `checksum` | string | 完整内容 SHA-256(用于 ETag) |
| `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 | 风险规则版本号 |
---
## 六、预览模式与两阶段发布
### 预览版 vs 正式版
PAR 快照分为两个状态:
| 状态 | 说明 | 谁可见 |
|------|------|--------|
| **预览版 (draft)** | 管理员保存后生效,未上传 CDN | MediaBot 带 `?preview=true` 可见 |
| **正式版 (published)** | 管理员发布后生效,已上传 CDN | 所有请求默认可见 |
### 两阶段发布工作流
```
开发者提交配置 → 管理员审核通过 → 自动生成预览版
↓
管理员保存预览版(savePreview)
↓
MediaBot 通过 ?preview=true 验证预览版效果
↓
管理员发布正式版(publish)
↓
快照写入 CDN,所有 MediaBot 自动获取最新版
```
### MediaBot 如何使用预览版
```bash
# 正常获取正式版(默认)
curl http://par:9012/api/v1/snapshots/pthome
# 获取预览版(用于开发/测试环境验证新配置)
curl "http://par:9012/api/v1/snapshots/pthome?preview=true"
```
> 💡 建议 MediaBot 在开发/测试环境使用 `?preview=true`,生产环境使用默认(正式版)。
---
## 七、鉴权说明
**无变化**。所有配置读取接口(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}` 是新路径,底层数据源相同。