3.5 KiB
3.5 KiB
ADR-003-03: 通用部署接口设计
状态
已接受
日期
2026-02-03
背景
在“部署操作”需求中,我们需要实现一个核心服务来执行 Salesforce Metadata API 的 deploy 操作。
虽然需求 003-02(元数据类型定义)已经解决了如何将 Java 对象转换为 ZIP 包的问题,但 003-03 关注的是部署操作本身的执行。
我们需要决定 MetadataDeployService 的入口参数形式,即它应该接收原始的 ZIP 数据,还是接收结构化的 Java 对象并由自己负责序列化。
决策
选择方案 1:通用字节流接口 (Generic Byte Stream Interface)。
即 Service 方法签名类似于:
public AsyncResult deploy(byte[] zipFile, DeployOptions deployOptions);
理由
-
关注点分离 (Separation of Concerns):
- 生成:元数据的构建(Object -> XML -> ZIP)属于“元数据定义”或“打包”范畴(如 003-02)。
- 执行:部署操作(ZIP -> Salesforce -> Polling)属于“传输”或“执行”范畴(003-03)。
- 将两者解耦,使得部署服务不依赖于具体的元数据类型定义。
-
灵活性与通用性:
- 该接口不仅支持由系统内部生成(003-02)的 ZIP 包。
- 也支持用户直接上传的 ZIP 包(例如从其他 Org 导出或手动编写的)。
- 支持未来扩展其他元数据类型的部署,而无需修改部署服务的核心逻辑。
-
复用性:
- 003-02 中定义的
MetadataTypeService可以调用此通用接口进行部署,只需将生成的 ZIP 字节数组传递给它。
- 003-02 中定义的
-
架构一致性:
- 符合 Salesforce Metadata API 的设计原语(API 本身接收的就是 base64 编码的 ZIP 数据)。
后果
正面影响
- 极高的复用性:一个
deploy方法即可支持所有类型的元数据部署。 - 易于测试:可以通过传入预先准备好的 ZIP 文件测试部署逻辑,而无需依赖复杂的对象构建过程。
- 支持文件上传:Controller 层可以直接将
MultipartFile的字节流传递给 Service,无需中间转换。
负面影响
- 验证滞后:Service 层难以在调用 API 前验证 ZIP 包内容的合法性(如
package.xml是否存在),错误通常要在 API 返回后才能发现。- 缓解措施:可以在 Service 层增加可选的 ZIP 结构预检查逻辑,或者依赖 Salesforce 的校验机制(
checkOnly=true)。
- 缓解措施:可以在 Service 层增加可选的 ZIP 结构预检查逻辑,或者依赖 Salesforce 的校验机制(
替代方案
方案 2:强类型接口 (Typed Interface)
- 设计:Service 接收
Metadata抽象类或具体子类,内部调用序列化逻辑。 - 优点:类型安全,Service 可以完全控制 ZIP 包的生成质量。
- 缺点:
- 耦合度高:部署服务依赖于具体的元数据模型。
- 不支持外部 ZIP:无法部署用户上传的现成 ZIP 包。
- 扩展困难:每增加一种元数据类型,可能需要修改或适配部署接口。
方案 3:混合接口 (Hybrid Interface)
- 设计:提供重载方法,既支持
byte[]也支持Metadata对象。 - 优点:兼顾灵活性和便利性。
- 缺点:增加了 Service 的复杂度和维护成本,且对象转 ZIP 的逻辑可能与 003-02 重复。