665 lines
14 KiB
Markdown
665 lines
14 KiB
Markdown
# API 文档
|
||
|
||
## 元数据
|
||
- 需求编号:014-4
|
||
- 创建时间:2026-01-27
|
||
- 创建人:SSOT 架构师
|
||
- 状态:已完成
|
||
|
||
## API 概述
|
||
|
||
本 API 提供了元数据容器与原子性部署功能,基于 Salesforce Tooling API 的 MetadataContainer 机制,支持元数据容器生命周期管理、容器成员管理、异步部署请求和状态轮询与结果解析。
|
||
|
||
### 核心功能
|
||
1. **元数据容器生命周期管理**:创建容器、删除容器、查询容器、获取容器详情
|
||
2. **容器成员管理**:添加成员到容器,支持多种元数据类型
|
||
3. **异步部署请求**:创建部署请求,支持 CheckOnly 模式和测试执行
|
||
4. **状态轮询与结果解析**:查询部署状态、轮询部署状态、获取部署详情、解析编译错误、解析测试结果
|
||
|
||
### 技术栈
|
||
- Spring Boot 3.5.7
|
||
- 若依框架
|
||
- Salesforce WSC 0.0.1
|
||
|
||
### 基础路径
|
||
- 元数据容器管理:`/tooling/metadata-container`
|
||
- 部署管理:`/tooling/deployment`
|
||
|
||
### 统一响应格式
|
||
所有 API 接口均返回统一的响应格式:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 返回数据 |
|
||
|
||
## 接口列表
|
||
|
||
### 1. 创建容器接口
|
||
|
||
#### 功能描述
|
||
创建一个新的元数据容器,用于存放待部署的元数据成员。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/metadata-container/create`
|
||
|
||
#### 请求权限
|
||
`tooling:container:create`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| name | String | 是 | 容器名称,长度 1-255 字符 |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"name": "MyContainer"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| id | String | 容器 ID |
|
||
| name | String | 容器名称 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"id": "a0B5g000006l7VFEAY",
|
||
"name": "MyContainer",
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:容器名称冲突
|
||
- 501:创建容器失败
|
||
|
||
---
|
||
|
||
### 2. 删除容器接口
|
||
|
||
#### 功能描述
|
||
删除指定的元数据容器及其所有成员。
|
||
|
||
#### 请求方式
|
||
DELETE
|
||
|
||
#### 请求路径
|
||
`/tooling/metadata-container/delete/{id}`
|
||
|
||
#### 请求权限
|
||
`tooling:container:delete`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | String | 是 | 容器 ID(路径参数) |
|
||
|
||
#### 请求示例
|
||
```
|
||
DELETE /tooling/metadata-container/delete/a0B5g000006l7VFEAY
|
||
```
|
||
|
||
#### 响应参数
|
||
无
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功"
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:删除容器失败
|
||
- 501:容器不存在
|
||
|
||
---
|
||
|
||
### 3. 获取容器详情接口
|
||
|
||
#### 功能描述
|
||
获取指定容器的详细信息。
|
||
|
||
#### 请求方式
|
||
GET
|
||
|
||
#### 请求路径
|
||
`/tooling/metadata-container/get/{id}`
|
||
|
||
#### 请求权限
|
||
`tooling:container:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | String | 是 | 容器 ID(路径参数) |
|
||
|
||
#### 请求示例
|
||
```
|
||
GET /tooling/metadata-container/get/a0B5g000006l7VFEAY
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| id | String | 容器 ID |
|
||
| name | String | 容器名称 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"id": "a0B5g000006l7VFEAY",
|
||
"name": "MyContainer",
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:查询容器失败
|
||
- 501:容器不存在
|
||
|
||
---
|
||
|
||
### 4. 查询容器列表接口
|
||
|
||
#### 功能描述
|
||
查询符合条件的容器列表。
|
||
|
||
#### 请求方式
|
||
GET
|
||
|
||
#### 请求路径
|
||
`/tooling/metadata-container/list`
|
||
|
||
#### 请求权限
|
||
`tooling:container:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| name | String | 否 | 容器名称(模糊查询) |
|
||
|
||
#### 请求示例
|
||
```
|
||
GET /tooling/metadata-container/list?name=MyContainer
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| id | String | 容器 ID |
|
||
| name | String | 容器名称 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": [
|
||
{
|
||
"id": "a0B5g000006l7VFEAY",
|
||
"name": "MyContainer",
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:查询容器列表失败
|
||
|
||
---
|
||
|
||
### 5. 添加成员接口
|
||
|
||
#### 功能描述
|
||
向指定容器添加一个元数据成员。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/member/add`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:addMember`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| containerId | String | 是 | 容器 ID |
|
||
| metadataType | String | 是 | 元数据类型(ApexClass、ApexTrigger、ApexPage 等) |
|
||
| contentEntityId | String | 否 | 内容实体 ID(可选) |
|
||
| body | String | 是 | 代码内容 |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"containerId": "a0B5g000006l7VFEAY",
|
||
"metadataType": "ApexClass",
|
||
"body": "public class MyClass {\n public void myMethod() {\n System.debug('Hello World');\n }\n}"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| id | String | 成员 ID |
|
||
| containerId | String | 容器 ID |
|
||
| metadataType | String | 元数据类型 |
|
||
| contentEntityId | String | 内容实体 ID |
|
||
| body | String | 代码内容 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"id": "a0C5g000006l7VFEAY",
|
||
"containerId": "a0B5g000006l7VFEAY",
|
||
"metadataType": "ApexClass",
|
||
"contentEntityId": null,
|
||
"body": "public class MyClass {\n public void myMethod() {\n System.debug('Hello World');\n }\n}",
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:添加成员失败
|
||
- 501:容器不存在
|
||
|
||
---
|
||
|
||
### 6. 部署容器接口
|
||
|
||
#### 功能描述
|
||
触发指定容器的部署,支持 CheckOnly 模式和测试执行。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/deploy`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:deploy`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| containerId | String | 是 | 容器 ID |
|
||
| isCheckOnly | Boolean | 是 | 是否仅检查(true:仅检查不部署,false:实际部署) |
|
||
| isRunTests | Boolean | 是 | 是否运行测试(true:运行测试,false:不运行测试) |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"containerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| id | String | 请求 ID |
|
||
| state | String | 部署状态(Queued、InProgress、Completed、Failed) |
|
||
| metadataContainerId | String | 容器 ID |
|
||
| isCheckOnly | Boolean | 是否仅检查 |
|
||
| isRunTests | Boolean | 是否运行测试 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"id": "1DR5g000006l7VFEAY",
|
||
"state": "Queued",
|
||
"metadataContainerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true,
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:部署失败
|
||
- 501:容器不存在
|
||
- 502:容器为空(没有成员)
|
||
- 503:并发部署限制
|
||
|
||
---
|
||
|
||
### 7. 查询部署状态接口
|
||
|
||
#### 功能描述
|
||
查询指定部署请求的状态。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/status/check`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| requestId | String | 是 | 请求 ID |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"requestId": "1DR5g000006l7VFEAY"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| requestId | String | 请求 ID |
|
||
| state | String | 部署状态(Queued、InProgress、Completed、Failed) |
|
||
| metadataContainerId | String | 容器 ID |
|
||
| isCheckOnly | Boolean | 是否仅检查 |
|
||
| isRunTests | Boolean | 是否运行测试 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"requestId": "1DR5g000006l7VFEAY",
|
||
"state": "Completed",
|
||
"metadataContainerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true,
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:查询状态失败
|
||
- 501:请求不存在
|
||
|
||
---
|
||
|
||
### 8. 轮询部署状态接口
|
||
|
||
#### 功能描述
|
||
轮询指定部署请求的状态,直到完成或超时。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/status/poll`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| requestId | String | 是 | 请求 ID |
|
||
| maxRetries | Integer | 否 | 最大重试次数(默认 60) |
|
||
| intervalMillis | Long | 否 | 轮询间隔(毫秒,默认 1000) |
|
||
|
||
#### 请求示例
|
||
```
|
||
POST /tooling/deployment/status/poll?requestId=1DR5g000006l7VFEAY&maxRetries=60&intervalMillis=1000
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| requestId | String | 请求 ID |
|
||
| state | String | 部署状态(Queued、InProgress、Completed、Failed) |
|
||
| metadataContainerId | String | 容器 ID |
|
||
| isCheckOnly | Boolean | 是否仅检查 |
|
||
| isRunTests | Boolean | 是否运行测试 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"requestId": "1DR5g000006l7VFEAY",
|
||
"state": "Completed",
|
||
"metadataContainerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true,
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:轮询状态失败
|
||
- 501:请求不存在
|
||
- 502:轮询超时
|
||
|
||
---
|
||
|
||
### 9. 获取部署详情接口
|
||
|
||
#### 功能描述
|
||
获取指定部署请求的详细信息,包括编译错误和测试结果。
|
||
|
||
#### 请求方式
|
||
POST
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/details/get`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| requestId | String | 是 | 请求 ID |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"requestId": "1DR5g000006l7VFEAY"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| requestId | String | 请求 ID |
|
||
| state | String | 部署状态(Queued、InProgress、Completed、Failed) |
|
||
| metadataContainerId | String | 容器 ID |
|
||
| isCheckOnly | Boolean | 是否仅检查 |
|
||
| isRunTests | Boolean | 是否运行测试 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
| componentFailures | Array | 编译错误列表 |
|
||
| runTestResult | Object | 测试结果 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"requestId": "1DR5g000006l7VFEAY",
|
||
"state": "Completed",
|
||
"metadataContainerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true,
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z",
|
||
"componentFailures": [],
|
||
"runTestResult": {
|
||
"numFailures": 0,
|
||
"numTestsRun": 1,
|
||
"totalTime": 123
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:获取详情失败
|
||
- 501:请求不存在
|
||
|
||
---
|
||
|
||
### 10. 获取部署结果接口
|
||
|
||
#### 功能描述
|
||
获取指定部署请求的部署结果,包括编译错误和测试结果。
|
||
|
||
#### 请求方式
|
||
GET
|
||
|
||
#### 请求路径
|
||
`/tooling/deployment/result/{requestId}`
|
||
|
||
#### 请求权限
|
||
`tooling:deployment:query`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| requestId | String | 是 | 请求 ID(路径参数) |
|
||
|
||
#### 请求示例
|
||
```
|
||
GET /tooling/deployment/result/1DR5g000006l7VFEAY
|
||
```
|
||
|
||
#### 响应参数
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| requestId | String | 请求 ID |
|
||
| state | String | 部署状态(Queued、InProgress、Completed、Failed) |
|
||
| metadataContainerId | String | 容器 ID |
|
||
| isCheckOnly | Boolean | 是否仅检查 |
|
||
| isRunTests | Boolean | 是否运行测试 |
|
||
| createdDate | String | 创建时间 |
|
||
| lastModifiedDate | String | 最后修改时间 |
|
||
| componentFailures | Array | 编译错误列表 |
|
||
| runTestResult | Object | 测试结果 |
|
||
|
||
#### 成功示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"requestId": "1DR5g000006l7VFEAY",
|
||
"state": "Completed",
|
||
"metadataContainerId": "a0B5g000006l7VFEAY",
|
||
"isCheckOnly": false,
|
||
"isRunTests": true,
|
||
"createdDate": "2026-01-27T10:00:00.000Z",
|
||
"lastModifiedDate": "2026-01-27T10:00:00.000Z",
|
||
"componentFailures": [],
|
||
"runTestResult": {
|
||
"numFailures": 0,
|
||
"numTestsRun": 1,
|
||
"totalTime": 123
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
- 500:获取结果失败
|
||
- 501:请求不存在
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
### 通用错误码
|
||
| 错误码 | 说明 |
|
||
|--------|------|
|
||
| 200 | 操作成功 |
|
||
| 500 | 操作失败 |
|
||
| 501 | 资源不存在 |
|
||
|
||
### 元数据容器错误码
|
||
| 错误码 | 说明 |
|
||
|--------|------|
|
||
| 500 | 创建容器失败 |
|
||
| 501 | 容器不存在 |
|
||
| 502 | 容器名称冲突 |
|
||
|
||
### 部署错误码
|
||
| 错误码 | 说明 |
|
||
|--------|------|
|
||
| 500 | 部署失败 |
|
||
| 501 | 请求不存在 |
|
||
| 502 | 容器为空(没有成员) |
|
||
| 503 | 并发部署限制 |
|
||
| 504 | 轮询超时 |
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
- [需求文档](../requirements/REQ-014-4.md)
|
||
- [设计文档](../design/2026-01-27-014-4-元数据容器与原子性部署-设计.md)
|
||
- [决策记录](../decisions/adr/2026-01-27-014-4-ADR-元数据容器与原子性部署技术选型.md)
|
||
- [提示词](../prompts/2026-01-27-014-4-prompt-元数据容器与原子性部署.md)
|