From 064a68d2a3ef5690f945a89be4d76321bbf7b6bc Mon Sep 17 00:00:00 2001 From: dark Date: Thu, 16 Apr 2026 10:57:48 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85pi=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/prod-api-v1.md | 424 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 docs/prod-api-v1.md diff --git a/docs/prod-api-v1.md b/docs/prod-api-v1.md new file mode 100644 index 0000000..7639612 --- /dev/null +++ b/docs/prod-api-v1.md @@ -0,0 +1,424 @@ +# 生产端配置同步接口文档 V1 + +## 1. 文档目的 + +本文档定义生产端提供给同步工具使用的接口协议,用于支持以下两类能力: + +- 接收开发侧下发的配置包并导入生产环境 +- 向同步工具提供当前生产环境配置快照 + +本文档面向: + +- 生产端接口开发人员 +- 同步工具开发人员 +- 联调与运维人员 + +## 2. 适用范围 + +本文档适用于“基于 FTP 中转的配置双向同步工具”中的生产端接口。 + +当前接口版本: + +- `V1` + +生产端建议提供两个接口: + +- `POST /api/config/push` +- `GET /api/config/pull` + +## 3. 设计原则 + +- 接口必须可被自动化任务调用,不依赖人工交互 +- `push` 必须具备幂等能力,避免重复导入 +- `pull` 必须返回当前生产正在生效的配置快照 +- 返回结果要足够明确,便于同步工具决定是否写 ACK +- 接口协议尽量简单,优先保证稳定性和可追踪性 + +## 4. 认证与安全 + +### 4.1 认证方式 + +建议使用: + +- `Bearer Token` + +请求头示例: + +```http +Authorization: Bearer xxxxxxxxxxxxx +``` + +### 4.2 传输协议 + +建议使用: + +- `HTTPS` + +### 4.3 调用方 + +仅允许生产环境内部部署的 `prod-agent` 调用。 + +## 5. 公共约定 + +### 5.1 公共请求头 + +建议所有请求携带以下 Header: + +| Header | 必填 | 说明 | +| --- | --- | --- | +| `Authorization` | 是 | Bearer Token | +| `Content-Type` | `push` 必填 | `multipart/form-data` | +| `Accept` | 否 | 推荐 `application/json` | +| `X-Trace-Id` | 否 | 同步链路跟踪号,可与报文中的 `traceId` 一致 | + +### 5.2 公共响应体 + +除 `pull` 成功场景外,建议统一返回 JSON: + +```json +{ + "code": "SUCCESS", + "message": "Operation succeeded", + "traceId": "4ec9506b4edf438ab6b6f7764e2d1d28", + "timestamp": "2026-04-16T10:20:30+08:00", + "data": {} +} +``` + +字段说明: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `code` | string | 业务码 | +| `message` | string | 说明信息 | +| `traceId` | string | 链路追踪号 | +| `timestamp` | string | 接口返回时间,ISO-8601 格式 | +| `data` | object | 业务数据 | + +### 5.3 公共业务码 + +| code | 说明 | +| --- | --- | +| `SUCCESS` | 处理成功 | +| `ACCEPTED` | 已接收,异步处理中 | +| `INVALID_PARAM` | 参数错误 | +| `UNAUTHORIZED` | 认证失败 | +| `FORBIDDEN` | 无权限 | +| `DUPLICATE_REQUEST` | 重复请求 | +| `PACKAGE_VALIDATE_FAILED` | 包校验失败 | +| `CONFIG_IMPORT_FAILED` | 配置导入失败 | +| `CONFIG_NOT_FOUND` | 当前无可导出的生产配置 | +| `INTERNAL_ERROR` | 系统内部异常 | + +说明: + +- 当前同步工具实现更适合同步处理,因此 `push` 推荐返回 `SUCCESS`,不建议首版做异步。 + +## 6. 配置包约定 + +`push` 接口接收的文件建议为 zip 包,结构如下: + +```text +package.zip + |- manifest.json + |- config/ + |- sha256.txt +``` + +### 6.1 manifest.json 示例 + +```json +{ + "traceId": "4ec9506b4edf438ab6b6f7764e2d1d28", + "direction": "DEV_TO_PROD", + "sourceEnv": "DEV", + "sourceVersion": "c1d2e3f4", + "contentHash": "b0f8f1d0ef7b7f0b8cb72a1cbf877f49d2d4073c8444a64eb8fd2e684cb7fe53", + "createdAt": "2026-04-16T10:18:00+08:00", + "packageName": "dev_to_prod-c1d2e3f4-4ec9506b4edf438ab6b6f7764e2d1d28.zip" +} +``` + +### 6.2 生产端校验要求 + +生产端在导入前建议至少执行以下校验: + +1. zip 包可正常解压 +2. `manifest.json` 存在且字段完整 +3. `config/` 目录存在 +4. `manifest.contentHash` 与实际内容哈希一致 +5. `direction` 必须为 `DEV_TO_PROD` +6. 同一个 `traceId` 或同一个 `sourceVersion + contentHash` 不重复导入 + +## 7. 接口一:推送配置到生产 + +### 7.1 接口信息 + +- 方法:`POST` +- 路径:`/api/config/push` +- 说明:接收开发侧配置包并导入生产环境 + +### 7.2 请求格式 + +`Content-Type`: + +- `multipart/form-data` + +表单字段定义: + +| 字段 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | +| `file` | file | 是 | 配置 zip 包 | +| `traceId` | string | 是 | 同步链路唯一标识 | +| `direction` | string | 是 | 固定为 `DEV_TO_PROD` | +| `sourceVersion` | string | 是 | 开发侧来源版本号,通常为 Git Commit ID | +| `contentHash` | string | 是 | 配置内容哈希 | + +### 7.3 curl 示例 + +```bash +curl -X POST "https://prod.example.com/api/config/push" \ + -H "Authorization: Bearer xxxxxxxxxxxxx" \ + -H "Accept: application/json" \ + -F "file=@dev_to_prod-c1d2e3f4-4ec9506b4edf438ab6b6f7764e2d1d28.zip" \ + -F "traceId=4ec9506b4edf438ab6b6f7764e2d1d28" \ + -F "direction=DEV_TO_PROD" \ + -F "sourceVersion=c1d2e3f4" \ + -F "contentHash=b0f8f1d0ef7b7f0b8cb72a1cbf877f49d2d4073c8444a64eb8fd2e684cb7fe53" +``` + +### 7.4 成功响应示例 + +```json +{ + "code": "SUCCESS", + "message": "Configuration imported successfully", + "traceId": "4ec9506b4edf438ab6b6f7764e2d1d28", + "timestamp": "2026-04-16T10:20:30+08:00", + "data": { + "applied": true, + "sourceVersion": "c1d2e3f4", + "contentHash": "b0f8f1d0ef7b7f0b8cb72a1cbf877f49d2d4073c8444a64eb8fd2e684cb7fe53", + "importTime": "2026-04-16T10:20:30+08:00" + } +} +``` + +### 7.5 重复请求响应示例 + +```json +{ + "code": "DUPLICATE_REQUEST", + "message": "The same package has already been applied", + "traceId": "4ec9506b4edf438ab6b6f7764e2d1d28", + "timestamp": "2026-04-16T10:20:35+08:00", + "data": { + "applied": true, + "sourceVersion": "c1d2e3f4", + "contentHash": "b0f8f1d0ef7b7f0b8cb72a1cbf877f49d2d4073c8444a64eb8fd2e684cb7fe53" + } +} +``` + +说明: + +- 对同步工具而言,`DUPLICATE_REQUEST` 可以按成功处理。 + +### 7.6 失败响应示例 + +```json +{ + "code": "PACKAGE_VALIDATE_FAILED", + "message": "Package content hash mismatch", + "traceId": "4ec9506b4edf438ab6b6f7764e2d1d28", + "timestamp": "2026-04-16T10:20:40+08:00", + "data": {} +} +``` + +### 7.7 HTTP 状态码建议 + +| HTTP 状态码 | 场景 | +| --- | --- | +| `200` | 导入成功或重复导入 | +| `400` | 参数缺失、方向错误、文件格式错误 | +| `401` | Token 无效 | +| `403` | 无权限 | +| `409` | 幂等冲突或状态冲突 | +| `422` | 包内容校验失败、配置业务校验失败 | +| `500` | 服务端异常 | + +### 7.8 处理语义 + +`push` 接口建议采用同步处理语义: + +1. 接收请求 +2. 校验包 +3. 导入并应用配置 +4. 成功后返回 `200` + +说明: + +- 同步工具当前在收到 `2xx` 后会回写 FTP ACK,因此生产端若采用异步处理,会导致工具提前判定成功。 +- 如后续要改异步,需要同时调整同步工具 ACK 逻辑。 + +## 8. 接口二:拉取生产配置快照 + +### 8.1 接口信息 + +- 方法:`GET` +- 路径:`/api/config/pull` +- 说明:返回当前生产环境已生效配置的快照 + +### 8.2 请求格式 + +当前 V1 版不要求请求参数。 + +curl 示例: + +```bash +curl -X GET "https://prod.example.com/api/config/pull" \ + -H "Authorization: Bearer xxxxxxxxxxxxx" +``` + +### 8.3 成功响应约定 + +成功时返回: + +- `HTTP 200` +- `Content-Type: application/json;charset=UTF-8` + +推荐响应头: + +| Header | 必填 | 说明 | +| --- | --- | --- | +| `X-Config-Version` | 推荐 | 当前生产配置版本号 | +| `X-Config-Hash` | 推荐 | 当前配置内容哈希 | +| `ETag` | 可选 | 可作为版本标识备用 | + +说明: + +- 当前同步工具优先读取 `X-Config-Version`,其次读取 `ETag`,如果都没有则退化为以内容哈希作为版本号。 + +### 8.4 成功响应体示例 + +```json +{ + "systemCode": "PAY_CENTER", + "version": "2026.04.16.01", + "profiles": [ + { + "name": "default", + "items": [ + { + "key": "feature.switch.payment", + "value": "true" + }, + { + "key": "payment.timeout.seconds", + "value": "30" + } + ] + } + ] +} +``` + +### 8.5 成功响应头示例 + +```http +HTTP/1.1 200 OK +Content-Type: application/json;charset=UTF-8 +X-Config-Version: 2026.04.16.01 +X-Config-Hash: 3d96f8d4c6d6d7cfcb1dc3d2c335ad426376cf2f774ab5b5567f7f8e9b30b5d1 +``` + +### 8.6 无配置场景示例 + +```json +{ + "code": "CONFIG_NOT_FOUND", + "message": "No active production configuration found", + "traceId": "server-generated-trace-id", + "timestamp": "2026-04-16T10:30:00+08:00", + "data": {} +} +``` + +### 8.7 HTTP 状态码建议 + +| HTTP 状态码 | 场景 | +| --- | --- | +| `200` | 成功返回配置快照 | +| `204` | 无可导出配置 | +| `401` | Token 无效 | +| `403` | 无权限 | +| `500` | 服务端异常 | + +说明: + +- 当前同步工具对 `204` 尚未做专门分支处理,如果生产端预计长期存在“无配置”场景,建议工具侧后续补充兼容逻辑。 + +## 9. 幂等规则 + +### 9.1 push 幂等建议 + +生产端建议以下任一方式作为幂等判断条件: + +1. `traceId` +2. `sourceVersion + contentHash` + +建议优先: + +- `traceId` + +补充校验: + +- 如果 `traceId` 相同但 `contentHash` 不同,应返回冲突错误,不允许覆盖 + +## 10. 审计建议 + +生产端建议记录以下审计信息: + +- `traceId` +- 调用时间 +- 调用方 IP +- 来源版本号 +- 内容哈希 +- 导入结果 +- 失败原因 + +## 11. 联调建议 + +联调时建议优先确认以下内容: + +1. `Authorization` 认证是否打通 +2. `push` 是否按 `multipart/form-data` 接收 +3. `pull` 是否返回原始 JSON 字节流 +4. `X-Config-Version` 是否稳定返回 +5. 重复请求是否能幂等处理 + +## 12. 与当前同步工具实现的对应关系 + +当前同步工具中的生产接口调用实现文件为: + +- [ProdConfigApiService.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/service/ProdConfigApiService.java) + +目前工具侧已按以下假设实现: + +- `push` 使用 `POST + multipart/form-data` +- `pull` 使用 `GET` +- `pull` 成功后将响应体直接保存为本地文件 `prod-config.json` +- `pull` 优先从 `X-Config-Version` 或 `ETag` 中提取版本号 + +因此本接口文档与当前工具实现是兼容的。 + +## 13. 后续可扩展项 + +后续如需增强,可在 V2 中考虑: + +- `push` 增加签名校验 +- `pull` 支持增量拉取 +- `pull` 增加查询参数,如 `systemCode`、`profile`、`version` +- `push` 增加灰度导入、预校验模式 +- 增加 `/api/config/validate` 预校验接口