FtpTool/docs/prod-api-v1.md
2026-04-16 10:57:48 +08:00

425 lines
9.9 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.

# 生产端配置同步接口文档 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` 预校验接口