# 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)