部署和检索元数据

使用 deploy() 和 retrieve() 调用移动元数据(XML 文件) 在 Salesforce 组织和本地文件系统之间。检索 XML 文件后 在文件系统中,您可以在源代码控制系统中管理更改,复制和粘贴 代码或设置配置,对组件进行差异更改,并执行许多其他基于文件的操作 开发操作。您可以随时将这些更改部署到另一个 Salesforce 组织。

注意

Ant 迁移工具使用 deploy() 和 retrieve() 调用来移动元数据。 如果您使用这些工具,则与元数据 API 的交互是无缝且不可见的。因此 大多数开发人员发现使用这些工具比编写直接调用 deploy() 和 retrieve() 的代码要容易得多。

XML 文件中的数据使用英语(美国)区域设置进行格式设置。此格式 确保对依赖于区域设置的字段(如日期字段)的解释一致 在使用不同语言的组织之间进行数据迁移期间。组织可以 支持多种语言向用户展示。

deploy() 和 retrieve() 调用主要用于 以下开发方案:

  • 在沙盒组织中开发自定义应用程序(或自定义)。后 完成开发和测试,然后部署应用程序或自定义项 使用元数据 API 进入生产组织。
  • 在 Developer Edition 组织中对应用程序进行团队开发。开发后 并完成测试,然后您可以通过 Lightning Platform 分发应用程序 AppExchange。

每次检索到最大数量的 90% 或更多时,您都会收到 API 通知 您可以使用元数据 API 一次性部署的自定义字段。自定义的最大数量 一个部署的字段为 45,000。在一个包.xml文件中检索到的自定义字段包括: 1) package.xml 的 CustomObjects 部分中每个对象的字段总和和 2) package.xml 的 CustomFields 部分中自定义字段的总和。

您仍然可以检索超过可部署最大值,直至达到检索文件总大小的限制。但是你 必须使用多个部署来部署所有自定义字段。

警告:您已检索到 47,000 个 CustomField 实例。无法重新部署所有这些 实例;最大值为 45,000。

使用 Zip 文件部署和检索元数据

和调用用于部署和检索 .zip 文件。在 .zip 文件是一个项目清单 (package.xml),其中列出了要执行的操作 检索或部署,以及组织到文件夹中的一个或多个 XML 组件。

deploy()retrieve()

注意

组件是元数据类型的实例。例如,是自定义对象的元数据类型,并且 该组件是 自定义对象。CustomObjectMyCustomObject__c

在 .zip 文件中检索或部署的文件可能是未打包的组件 驻留在组织中(例如标准对象)或打包组件 驻留在命名包中。

注意

您可以部署或 一次最多可检索 10,000 个文件。AppExchange 软件包使用不同的限制: 最多可包含 35,000 个文件。已部署或检索的 .zip 的最大大小 文件大小为 39 MB。如果文件在解压缩的文件夹中解压缩,则大小限制 是 400 MB。

  • 如果使用 Ant 迁移工具执行 部署解压后的文件夹,首先压缩文件夹中的所有文件。这 解压缩文件夹中未压缩组件的最大大小为 400 MB 或更少 取决于压缩比。如果文件具有高压缩比, 您总共可以迁移大约 400 MB,因为压缩的大小 将小于 39 MB。但是,如果组件不能被压缩太多,比如 二进制静态资源,可以迁移小于 400 MB。
  • 元数据 API base-64 对组件进行编码 它们被压缩了。生成的 .zip 文件不能超过 50 MB,即 SOAP 消息的限制。Base-64 编码会增加有效负载的大小,因此 在编码之前,压缩的有效负载不能超过大约 39 MB。
  • 您可以执行大 对象仅在定义其索引时才被定义。如果在安装程序中创建了一个大对象,并且 尚未定义索引,则无法检索它。retrieve()

每个 .zip 文件都包含一个项目清单、一个名为 package.xml 的文件以及一组包含 组件。清单文件定义您尝试执行的组件 在 .zip 文件中检索或部署。清单还定义了 API 版本 用于部署或检索。

注意

您可以编辑项目 清单,但如果您修改它所包含的组件列表,请小心。当你 部署或检索组件时,元数据 API 会引用 清单,而不是 .zip 文件中的目录。

下面是一个示例包 .xml 文件。您可以检索 通过在元素中指定元数据类型的 fullName 字段值来获取元数据类型的单个组件。您还可以 使用 检索元数据类型的所有组件。members<members>*</members>

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MyCustomObject__c</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomTab</name>
    </types>
    <types>
        <members>Standard</members>
        <name>Profile</name>
    </types>
    <version>59.0</version>
</Package>

可以在 package.xml 中定义以下元素。

  • <fullName>包含服务器端的名称 包。如果不存在,则 package.xml 定义客户端包。<fullName>unpackaged
  • <types>包含元数据类型的名称 (例如,) 和 成员(例如,) 为 检索或部署。您可以在清单文件中添加多个元素。CustomObjectmyCustomObject__c<types>
  • <members>包含组件的 fullName,例如 。listMetadata() 调用可用于 确定特定组件的 fullName 元数据类型(如果要检索单个组件)。对于许多元数据 类型,您可以将 中的值替换为通配符(星号) 而不是单独列出每个成员。有关特定 type 以确定该类型是否支持通配符。 每个组件 在元数据 API 部署中必须具有唯一的名称。解析为 重复项,例如一个符号和 UTF-8 编码符号以及一对名为 xyz.typename 和 xyz.typename-meta.xml 仍然是 重复。MyCustomObject__cmembers*注意在元素中指定 Security,在名称中指定 Settings 元素。<members>
  • <name>包含元数据类型,例如 或 。在 目录。任何扩展元数据的元数据类型都是有效值。输入的名称 必须与元数据 API WSDL 中定义的元数据类型匹配。有关列表,请参阅元数据类型。CustomObjectProfile
  • <version>是使用的 API 版本号 部署或检索 .zip 文件时。当前有效值为 。59.0

有关演示如何工作的更多示例包 .xml 清单文件 使用不同的元数据子集,请参阅示例包 .xml 清单 文件。

要删除组件,请参阅从 组织。

部署缓慢

如果在服务器停机期间进行基于文件的元数据 API 部署,例如 Salesforce 服务升级时,部署所需的时间可能比预期的要长。发生此行为 因为组件部署和验证都是从头开始重试的,所以在 服务已恢复。但是,如果 Apex 测试是部署的一部分,则只有不是部署的测试 在停机时间运行之前运行。

此行为会影响基于文件的部署和检索、更改集、某些包安装 和升级、第二代托管软件包创建以及部署和检索已开始 从 Salesforce CLI 或 Salesforce VS Code 扩展。它不影响基于 CRUD 元数据操作。

如果您的实例需要进行计划的服务升级,请避免在 服务升级。要检查您的 Salesforce 实例是否需要升级,请检查 Salesforce 信任。Salesforce 每年执行 3 次重大服务升级和其他 全年维护更新。

检索作业的状态是否为“挂起”?

如果为单个启动多个并发检索操作 org,元数据 API 会自动将其中一些作业放入队列中,如果有必要的话 服务保护。如果检索作业的状态为 ,则为 在队列中。当其中一个活动检索作业完成时,元数据 API 将接受挂起的作业 从队列中激活它。如果检索作业的状态为 ,则该作业处于活动状态。该过程将重复进行,直到作业队列 清除。PendingInProgress

有关更多信息,请参阅 Salesforce 开发人员限制和分配快速中的元数据限制 参考资料。

示例包 .xml 清单文件

本部分包括示例包 .xml 清单文件,这些文件演示如何工作 具有不同的元数据子集。清单文件可以包含多个<类型>元素 因此,如果需要,可以将各个示例合并到一个 Package.xml 清单文件中 在一个批处理中处理所有元数据。

列出了以下示例:

  • 标准 对象
  • 全部定制 对象
  • 标准选择列表 领域
  • 定制和标准 领域
  • 标准列表视图 对象
  • 安全 设置
  • 分配规则,自动响应 规则、升级规则
  • 共享规则
  • 托管组件 访问

有关清单文件结构的更多信息,请参阅使用 Zip 文件部署和检索元数据。

标准对象

此示例包 .xml 清单文件说明了如何工作 替换为标准 Account 对象。检索或部署标准对象包括 所有自定义字段和标准字段,但不可自定义的标准字段除外。 支持所有自定义字段。只有您可以自定义的标准字段是 支持,即可以添加帮助文本或启用的标准字段 历史记录跟踪或 Chatter 摘要跟踪。其他标准字段不是 支持,包括系统字段(如 CreatedById 或 LastModifiedDate)和自动编号字段。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account</members>
        <name>CustomObject</name>
    </types>
    <version>59.0</version>
</Package>

请注意如何使用标准 Account 对象,方法是将其指定为 CustomObject 类型。但是,您不能使用星号通配符来处理所有 标准对象;每个标准对象必须按名称指定。

所有自定义对象

此示例包 .xml 清单文件说明了如何工作 替换为所有自定义对象。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <version>59.0</version>
</Package>

此清单文件可用于检索或部署所有自定义对象,但不是全部 标准对象。

标准选择列表字段

在 API 版本 38.0 及更高版本中,StandardValueSet 类型表示标准 选择列表。选择列表不再像早期版本那样由字段表示。 此示例包 .xml 将行业标准选择列表表示为 StandardValueSet 类型。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Industry</members>
        <name>StandardValueSet</name>
    </types>
    <version>59.0</version>
</Package>

注意

标准值集的名称区分大小写。

行业标准值集对应于 API 版本 37.0 及更早版本中的 Account.Industry 或 Lead.Industry 字段。此示例显示 Account.Industry 选择列表的 package.xml 示例。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.Industry</members>
        <name>CustomField</name>
    </types>
    <version>37.0</version>
</Package>

注意

选择列表字段的名称区分大小写。

请注意字段中的语法,其中是对象的名称,例如 和 标准选择列表字段的名称,例如“行业”。objectName.picklistField<members>objectNameAccountpicklistField

下一个 package.xml 示例表示商机团队角色 在 API 版本 38.0 及更高版本中。将商机团队角色指定为 SalesTeamRole 标准值集。商机团队角色 具有与“客户团队”角色相同的选择列表值。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>SalesTeamRole</members>
        <name>StandardValueSet</name>
    </types>
    <version>59.0</version>
</Package>

SalesTeamRole 标准值集对应于以下值之一 API 版本 37.0 及更早版本中的字段名称:OpportunityTeamMember.TeamMemberRole、UserAccountTeamMember.TeamMemberRole、UserTeamMember.TeamMemberRole 和 AccountTeamMember.TeamMemberRole。 商机团队角色 在此示例包 .xml 中表示为 OpportunityTeamMember.TeamMemberRole 字段。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>OpportunityTeamMember.TeamMemberRole</members>
        <name>CustomField</name>
    </types>
    <version>37.0</version>
</Package>

了解标准值集的名称以及它们如何映射到选择列表字段 名称,请参阅 StandardValueSet 名称和标准选择列表字段。

自定义字段和标准字段

此示例包 .xml 清单文件说明了如何工作 在自定义和标准对象中使用自定义字段,在标准中使用标准字段 对象。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MyCustomObject__c.MyCustomField__c</members>
        <name>CustomField</name>
    </types>
    <types>
        <members>Account.SLA__c</members>
        <members>Account.Phone</members>
        <name>CustomField</name>
    </types>
    <version>59.0</version>
</Package>

请注意 字段 where 是对象的名称(如 Account),是自定义或标准字段的名称,例如表示服务级别协议的 SLA 选择列表字段 选择。MyCustomObject 中的 MyCustomField 自定义域 自定义对象由其全名 唯一标识。同样,“客户标准”对象中的“电话标准”字段为 由其全名 .objectName.field<members>objectNamefieldMyCustomObject__c.MyCustomField__cAccount.Phone

支持所有自定义字段。只有您可以自定义的标准字段是 支持,即可以添加帮助文本或启用的标准字段 历史记录跟踪或 Chatter 摘要跟踪。其他标准字段不是 支持,包括系统字段(如 CreatedById 或 LastModifiedDate)和自动编号字段。

标准对象的列表视图

检索标准对象的列表视图的最简单方法是检索 对象。列表视图包含在检索到的组件中。请参阅部分 有关标准对象的本主题。

如果您不想检索所有 对象的详细信息。此示例包 .xml 清单文件 阐释如何使用标准 Account 对象的列表视图。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.AccountTeam</members>
        <name>ListView</name>
    </types>
    <version>59.0</version>
</Package>

请注意字段中的语法,其中是对象的名称,例如 Account,并且是 View Unique 列表视图的名称。如果检索此列表视图,则组件 存储在 objects/Account.object 中。objectName.listViewUniqueName<members>objectNamelistViewUniqueName

要检索包,请在调用 时在 RetrieveRequest 的 packageNames 字段中设置包的名称。包 .xml 清单文件 会自动填充到检索到的文件中。元素 在 package.xml 中包含检索到的包的名称。retrieve().zip<fullName>

如果在元素中使用星号通配符来检索特定元数据类型的所有组件,则检索到的 内容不包括托管包中的组件。<members>

有关托管包的详细信息,请参阅第二代托管包 打包开发人员指南。

检索托管包中的组件的最简单方法是检索 如前所述,通过在 的 packageNames 字段中设置包的名称来完成包。以下示例包.xml 清单文件演示了 检索包中的单个组件。RetrieveRequest

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>myns__MyCustomObject__c</members>
        <name>CustomObject</name>
    </types>
    <version>59.0</version>
</Package>

请注意字段中的 __ 语法,其中是包的命名空间前缀,是对象的名称。namespacePrefixobjectName<members>namespacePrefixobjectName命名空间前缀是 1 个字符到 15 个字符的字母数字标识符 将您的包及其内容与其他发布商的包区分开来 包。有关详细信息,请参阅创建和 为第二代托管注册命名空间 包。

安全设置

此示例包 .xml 清单文件说明了如何工作 使用组织的安全设置。在元素中指定 Security,在名称中指定 Settings 元素。<members>

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Security</members>
        <name>Settings</name>
    </types>
    <version>59.0</version>
</Package>

分配规则、自动响应规则、升级 规则

分配规则、自动响应规则和升级规则使用 用于访问规则集的不同包 .xml 类型名称或 对象类型的单个规则。例如,以下示例 package.xml 清单文件演示了如何访问 仅案例和潜在顾客的组织分配规则。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Case</members>
        <members>Lead</members>
        <name>AssignmentRules</name>
    </types>
    <version>59.0</version>
</Package>

以下示例包.xml 清单 文件说明了如何仅访问“samplerule” 案例分配规则 以及“newrule”潜在客户分配规则。请注意,类型名称是 and not 。

AssignmentRuleAssignmentRules

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Case.samplerule</members>
        <members>Lead.newrule</members>
        <name>AssignmentRule</name>
    </types>
    <version>59.0</version>
</Package>

同样,用于访问单个自动响应规则和 升级规则,使用 and 代替 和 。

AutoResponseRuleEscalationRuleAutoResponseRulesEscalationRules

共享规则

在 API 版本 33.0 及更高版本中,可以检索和部署所有共享规则 标准对象和自定义对象。此示例包 .xml 清单 文件说明了如何使用组织的共享规则,例如 检索潜在顾客对象的基于条件的特定共享规则,检索 所有对象的所有基于所有权的共享规则,并检索所有对象 Account 对象的基于区域的共享规则。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Lead.testShareRule</members> 
         <name>SharingCriteriaRule</name>
    </types>
    <types>
        <members>*</members> 
        <name>SharingOwnerRule</name>
    </types>
    <types>
        <members>Account.*</members>
        <name>SharingTerritoryRule</name>
    </types>
    <version>33.0</version>
</Package>

托管组件访问

在 API 版本 29.0 及更高版本中,您可以检索和 在配置文件中部署以下托管组件的访问设置,以及 权限集:

  • 顶点类
  • 应用程序
  • 自定义字段权限
  • 自定义对象权限
  • 自定义选项卡设置
  • 外部数据源
  • 记录类型
  • Visualforce 页面

在 API 版本 51.0 及更高版本中,您可以检索和部署登录的访问设置 流。

检索和部署托管组件权限时,请指定命名空间 后跟两个下划线。不支持通配符。

例如,假设您安装了一个命名空间为 MyNamespace 且自定义对象为 JobRequest__c 的托管包。将包中JobRequest__c的对象权限设置为自定义配置文件 MyProfile,您需要将以下内容添加到 .profile 文件中。

要部署,请执行以下操作:

<objectPermissions>
    <allowCreate>true</allowCreate>
    <allowDelete>true</allowDelete>
    <allowEdit>true</allowEdit>
    <allowRead>true</allowRead>
    <viewAllRecords>false</viewAllRecords>
    <modifyAllRecords>false</modifyAllRecords>
    <object>MyNamespace__JobRequest__c</object>
</objectPermissions>

要检索:

<types>
    <members>MyNamespace__JobRequest__c</members>
    <name>CustomObject</name>
</types>
<types>
    <members>MyProfile</members>
    <name>Profile</name>
</types>

检索权限集和配置文件时,请确保还检索任何 与权限和设置相关的组件。例如,当 检索应用程序可见性时,还必须检索关联的应用程序,以及何时检索 检索对象或字段权限时,还必须检索关联的 对象。

在部署中运行测试

生产环境中的默认测试执行

如果部署选项中未指定测试级别,则 默认测试执行行为取决于部署包的内容。什么时候 部署到生产环境后,除源自托管包的测试外,所有测试都是 如果您的部署包包含 Apex 类或触发器,则执行。如果您的包裹 不包含 Apex 组件,默认情况下不运行任何测试。

在 API 版本 33.0 及更早版本中,对以下组件运行了测试 所需的测试,例如自定义对象,而不仅仅是针对 Apex 组件。例如,如果 您的包包含一个自定义对象,所有测试都在 API 版本 33.0 及更早版本中运行。在 相比之下,从 API 版本 34.0 开始,不会对此包运行任何测试。API 版本 对应于 API 客户端的版本或您正在使用的工具的版本(Ant 迁移工具)。

您可以为非 Apex 组件的部署运行测试。您可以 通过在部署中设置测试级别来替代默认测试执行行为 选项。无论 部署包。我们建议您在开发中运行所有本地测试 环境,例如沙盒,然后再部署到生产环境。在 开发环境减少了在生产环境中运行所需的测试数量 部署。

API 版本 33.0 及更早版本的生产环境中的默认测试执行

若要部署到生产组织,将运行组织中的所有本地测试 默认情况下。默认情况下,源自已安装的托管包的测试不会运行。如果 任何测试失败,整个部署都将回滚。

如果部署包含以下元数据类型的组件,则所有本地测试都是 跑。

  • 顶点类
  • Apex组件
  • ApexPage(顶点页面)
  • Apex触发器
  • 文章类型
  • BaseSharingRule
  • CriteriaBasedSharingRule
  • 自定义字段
  • 自定义对象
  • 数据类别组
  • 已安装的软件包
  • NamedFilter(名称过滤器)
  • OwnerSharingRule
  • 权限集
  • 轮廓
  • 队列
  • 记录类型
  • RemoteSiteSetting
  • 角色
  • 共享原因
  • 领土
  • 验证规则
  • 工作流程

例如,不会对以下部署运行任何测试:

  • 1 CustomApplication 组件
  • 100 个报表组件和 40 个仪表板组件

但是,所有本地测试都针对以下任何示例部署运行,因为它们 包括上面列表中的至少一个组件:

  • 1 CustomField 组件
  • 1 个 ApexComponent 组件和 1 个 ApexClass 组件
  • 5 个 CustomField 组件和 1 个 ApexPage 组件
  • 100 个报表组件、40 个仪表板组件和 1 个 CustomField 组件

在部署中运行测试的子集

测试级别使你能够更好地控制在部署中运行哪些测试。自 缩短部署到生产的时间,在部署 Apex 组件时运行测试子集。这 生产环境中的默认测试执行行为也已更改。默认情况下,如果没有测试级别 指定时,不会执行任何测试,除非您的部署包包含 Apex 类或 触发器。

如果部署中某个 Apex 组件的代码覆盖率小于 75%,则部署 失败。如果指定的测试之一失败,则部署也会失败。我们建议您测试 首先在沙盒中部署,以确保指定的测试涵盖每个组件 充分。即使组织的整体代码覆盖率为 75% 或更高,个人 正在部署的 Apex 组件的覆盖范围可能较小。如果代码覆盖率要求 不满足,编写更多测试并将它们包含在部署中。

若要运行测试的子集,请设置测试 对象的级别。接下来,指定每个测试 要在 中运行的类。最后,作为参数传递给调用。以下示例执行这些步骤以仅运行指定的 测试类。RunSpecifiedTestsDeployOptionsDeployOptionsDeployOptionsdeploy()

// Create the DeployOptions object.
DeployOptions deployOptions = new DeployOptions();

// Set the appropriate test level.
deployOptions.setTestLevel(TestLevel.RunSpecifiedTests);

// Specify the test classes to run.
// String array contains test class names.
String[] tests = {"TestClass1", "TestClass2", "TestClass3"};
// Add the test class names array to the deployment options.
deployOptions.setRunTests(tests);

// Call deploy() by passing the deployment options object as an argument. 
AsyncResult asyncResult = metadatabinding.deploy(zipBytes,deployOptions);

有关运行特定测试的注意事项

  • 您只能指定测试类。不能指定单个测试方法。
  • 我们建议您重构测试类,以包含满足的最小测试数 代码覆盖率要求。重构测试类有助于缩短测试时间 执行时间,从而缩短部署时间。
  • 您可以通过使用非活动状态部署目标组织中的触发器来停用该触发器 州。但是,触发器必须以前已部署为活动状态。

在沙盒和生产部署中运行相同的测试

从 API 版本 34.0 开始,您可以选择在开发中运行哪些测试 环境,例如仅本地测试,以匹配在生产环境中运行的测试。在早期版本中, 如果在沙盒部署中启用了测试,则无法排除托管包 测试。

默认情况下,在部署到非生产组织(例如 沙盒或 Developer Edition 组织。指定要在开发中运行的测试 环境,设置 testLevel 部署 选项。例如,在部署中运行本地测试并排除托管包 tests,将对象上的 testLevel 设置为 。 接下来,将此对象作为参数传递给调用 如下。DeployOptionsTestLevel.RunLocalTestsdeploy()

// Create the DeployOptions object.
DeployOptions deployOptions = new DeployOptions();

// Set the appropriate test level.
deployOptions.setTestLevel(TestLevel.RunLocalTests);

// Call deploy() by passing the deployment options object as an argument. 
AsyncResult asyncResult = metadatabinding.deploy(zipBytes,deployOptions);

注意

无论 部署包的内容。相比之下,默认情况下,测试在生产环境中执行 仅当您的部署包包含 Apex 类或触发器时。可用于沙盒和生产部署。RunLocalTestsRunLocalTests

维护用户引用

在元数据部署期间保留用户字段。

当部署中的组件 指特定用户,例如工作流电子邮件的收件人 通知或仪表板运行用户,然后 Salesforce 尝试 通过比较在目标组织中查找匹配的用户 部署期间的用户名。

例如,当您将数据复制到沙盒时,包含来自生产组织的用户名的字段 更改为包含沙盒名称。在名为 的沙盒中,用户名变为 。当您部署 沙盒中的元数据,则用户名中的元数据将被忽略。testuser@acme.comuser@acme.com.testtest对于部署中的用户引用,Salesforce 执行 顺序如下:

  1. Salesforce 将源环境中的用户名与目标环境中的用户名进行比较 环境并调整组织域名。
  2. 如果两个或多个用户名匹配,Salesforce 会列出 匹配的名称和请求源环境中的一个用户 重命名。
  3. 如果源环境中的用户名不存在 目标环境,Salesforce 显示 错误,部署将停止,直到删除用户名 或解析为目标环境中的用户。

基于 CRUD 的元数据开发

使用基于 CRUD 的元数据调用创建、更新或删除设置和 组织或应用程序的配置组件。这些配置 组件包括自定义对象、自定义字段和其他配置元数据。这 元数据调用模仿 Salesforce 用户界面中用于创建、更新、 或删除组件。无论那里适用什么规则,也适用于这些调用。

元数据调用在这些方面与核心同步 API 调用不同。

  • 元数据 API 调用在单独的 WSDL 中可用。自 下载 WSDL,登录 Salesforce,从“设置”中,输入“快速查找”框,然后 选择 API,然后单击 Download Metadata WSDL 链接。API
  • 登录后,您必须将元数据 API 调用发送到元数据 API 端点。 其 URL 与 SOAP API 不同。从 返回的 LoginResult 中检索 metadataServerUrl SOAP API 调用。更多信息 关于 SOAP API,请参阅 SOAP API 开发人员 指南。login()
  • 元数据调用可以是同步的,也可以是异步的。CRUD 调用在 API 版本 30.0 及更高版本,与 API 核心调用类似,结果如下 在一次调用中返回。在早期 API 版本中,创建、更新和删除 只是异步的,这意味着结果不会立即返回 在一次通话中。
  • 有映射到相应核心 SOAP API 的同步元数据调用 同步调用。
    • createMetadata() 映射到 SOAP API 调用。create()
    • updateMetadata() 映射到 SOAP API 调用。update()
    • deleteMetadata() 映射到 SOAP API 调用。delete()

注意

元数据 API 还支持和调用检索和部署元数据 组件。有关更多信息,请参阅部署和检索元数据。retrieve()deploy()

使用同步调用进行基于 CRUD 的开发 Java 示例

本节将指导您完成使用基于 CRUD 的示例 Java 客户端应用程序 调用。此示例应用程序执行以下主要任务。

  1. 使用该类 创建元数据连接。有关更多信息,请参阅步骤 3:演练 Java 示例代码。MetadataLoginUtil.java
  2. 调用 createMetadata() 以创建自定义 对象。此调用在一次调用中返回结果。
  3. 将返回的对象检查到 检查操作是否成功,如果没有成功,则写入组件名称, 错误消息和状态代码。SaveResult
import com.sforce.soap.metadata.*;

/**
 * Sample that logs in and creates a custom object through the metadata API
 */
public class CRUDSampleCreate {
    private MetadataConnection metadataConnection;

    // one second in milliseconds
    private static final long ONE_SECOND = 1000;

    public CRUDSampleCreate() {
    }

    public static void main(String[] args) throws Exception {
        CRUDSampleCreate crudSample = new CRUDSampleCreate();
        crudSample.runCreate();
    }

    /**
     * Create a custom object. This method demonstrates usage of the
     * create() and checkStatus() calls.
     *
     * @param uniqueName Custom object name should be unique.
     */
    private void createCustomObjectSync(final String uniqueName) throws Exception {
        final String label = "My Custom Object";
        CustomObject co = new CustomObject();
        co.setFullName(uniqueName);
        co.setDeploymentStatus(DeploymentStatus.Deployed);
        co.setDescription("Created by the Metadata API Sample");
        co.setEnableActivities(true);
        co.setLabel(label);
        co.setPluralLabel(label + "s");
        co.setSharingModel(SharingModel.ReadWrite);

        // The name field appears in page layouts, related lists, and elsewhere.
        CustomField nf = new CustomField();
        nf.setType(FieldType.Text);
        nf.setDescription("The custom object identifier on page layouts, related lists etc");
        nf.setLabel(label);
        nf.setFullName(uniqueName);
        customObject.setNameField(nf);

        SaveResult[] results = metadataConnection
                .createMetadata(new Metadata[] { co });

        for (SaveResult r : results) {
            if (r.isSuccess()) {
                System.out.println("Created component: " + r.getFullName());
            } else {
                System.out
                        .println("Errors were encountered while creating "
                                + r.getFullName());
                for (Error e : r.getErrors()) {
                    System.out.println("Error message: " + e.getMessage());
                    System.out.println("Status code: " + e.getStatusCode());
                }
            }
        }
    }

    private void runCreate() throws Exception {
        metadataConnection = MetadataLoginUtil.login();
        // Custom objects and fields must have __c suffix in the full name.
        final String uniqueObjectName = "MyCustomObject__c";
        createCustomObjectSync(uniqueObjectName);
    }
}

使用异步调用进行基于 CRUD 的开发的 Java 示例

重要

本节中的示例取决于异步 CRUD 调用。异步 CRUD 调用是 no 从 API 版本 31.0 开始提供更长的时间,并且仅在早期 API 中可用 版本。create()

本节将指导您完成一个示例 Java 客户端应用程序,该应用程序使用 基于 CRUD 的异步调用。此示例应用程序执行以下主要操作 任务:

  1. 使用该类 创建元数据连接。有关更多信息,请参阅步骤 3:演练 Java 示例代码。MetadataLoginUtil.java
  2. 调用 create() 来创建一个 自定义对象。Salesforce 返回 的 AsyncResult 对象 您尝试创建的每个组件。AsyncResult 对象是 当操作从队列移动到 “已完成”或“错误”状态。
  3. 在循环中调用 checkStatus() 直到 AsyncResult 中的 status 值指示创建操作已完成。

请注意每个 API 调用后面的错误处理代码。

import com.sforce.soap.metadata.*;

/**
 * Sample that logs in and creates a custom object through the metadata api
 */
public class CRUDSample {
    private MetadataConnection metadataConnection;

    // one second in milliseconds
    private static final long ONE_SECOND = 1000;

    public CRUDSample() {
    }

    public static void main(String[] args) throws Exception {
        CRUDSample crudSample = new CRUDSample();
        crudSample.runCreate();
    }

    /**
     * Create a custom object. This method demonstrates usage of the
     * create() and checkStatus() calls.
     *
     * @param uniqueName Custom object name should be unique.
     */
    private void createCustomObject(final String uniqueName) throws Exception {
        final String label = "My Custom Object";
        CustomObject customObject = new CustomObject();
        customObject.setFullName(uniqueName);
        customObject.setDeploymentStatus(DeploymentStatus.Deployed);
        customObject.setDescription("Created by the Metadata API Sample");
        customObject.setLabel(label);
        customObject.setPluralLabel(label + "s");
        customObject.setSharingModel(SharingModel.ReadWrite);

        // The name field appears in page layouts, related lists, and elsewhere.
        CustomField nf = new CustomField();
        nf.setType(FieldType.Text);
        nf.setDescription("The custom object identifier on page layouts, related lists etc");
        nf.setLabel(label);
        nf.setFullName(uniqueName);
        customObject.setNameField(nf);

        AsyncResult[] asyncResults = metadataConnection.create(
            new CustomObject[]{customObject});
        if (asyncResults == null) {
            System.out.println("The object was not created successfully");
            return;
        }

        long waitTimeMilliSecs = ONE_SECOND;

        // After the create() call completes, we must poll the results of the checkStatus()
        // call until it indicates that the create operation has completed.
        do {
            printAsyncResultStatus(asyncResults);
            waitTimeMilliSecs *= 2;
            Thread.sleep(waitTimeMilliSecs);
            asyncResults = metadataConnection.checkStatus(new String[]{asyncResults[0].getId()});
        } while (!asyncResults[0].isDone());

        printAsyncResultStatus(asyncResults);
    }

    private void printAsyncResultStatus(AsyncResult[] asyncResults) throws Exception {
        if (asyncResults == null || asyncResults.length == 0 || asyncResults[0] == null) {
            throw new Exception("The object status cannot be retrieved");
        }

        AsyncResult asyncResult = asyncResults[0]; //we are creating only 1 metadata object

        if (asyncResult.getStatusCode() != null) {
            System.out.println("Error status code: " +
                    asyncResult.getStatusCode());
            System.out.println("Error message: " + asyncResult.getMessage());
        }

        System.out.println("Object with id:" + asyncResult.getId() + " is " +
            asyncResult.getState());
    }

    private void runCreate() throws Exception {
        metadataConnection = MetadataLoginUtil.login();
        // Custom objects and fields must have __c suffix in the full name.
        final String uniqueObjectName = "MyCustomObject__c";
        createCustomObject(uniqueObjectName);
    }
}

REST 资源

使用 REST 资源进行移动 Salesforce 组织与本地文件系统之间的元数据(XML 文件)。

deployRequest

XML 文件中的数据使用英语(美国)区域设置进行格式设置。这种方法 确保对依赖于区域设置的字段(如日期字段)的解释一致 在使用不同语言的组织之间进行数据迁移期间。组织可以 支持多种语言向用户展示。

元数据部署主要用于以下开发方案。

  • 在沙盒组织中开发自定义应用程序(或自定义)。后 完成开发和测试,然后部署应用程序或自定义项 使用元数据 API 进入生产组织。
  • 在 Developer Edition 组织中对应用程序进行团队开发。开发后 并完成测试,然后您可以通过 Lightning Platform 分发应用程序 AppExchange。

使用 Zip 文件

该资源用于部署 .zip 文件。在 .zip 文件中有一个项目清单 (package.xml) 列出要检索或部署的内容,以及组织到其中的一个或多个 XML 组件 文件夹。deployRequest

注意

组件是 元数据类型。 例如,是自定义对象的元数据类型,组件是 自定义对象的实例。CustomObjectMyCustomObject__c

部署在 .zip 文件中的文件可以解压缩 驻留在组织中的组件(例如标准对象)。这 文件也可以是驻留在命名包中的打包组件。

注意

一次最多可以部署 10,000 个文件。(在 API 版本 43.0 中 及更高版本,AppExchange 软件包最多可以包含 12,500 个文件。.zip 文件大小限制 适用于 SOAP 调用的不适用于 REST 资源。但是,400 MB 的组件限制 上传后解压缩到解压缩的文件夹中适用于 SOAP 和 REST 部署。deployRequest

每个 .zip 文件都包含一个项目清单、一个名为 package.xml 的文件以及一组包含组件的目录。 清单文件定义您尝试检索或部署的组件,以及 用于部署或检索的 API 版本。

下面是一个示例包 .xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MyCustomObject__c</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomTab</name>
    </types>
    <types>
        <members>Standard</members>
        <name>Profile</name>
    </types>
    <version>59.0</version>
</Package>

可以在 package.xml 中定义以下元素。

  • <fullName>包含服务器端的名称 包。如果不存在,则它是客户端包。<fullName>unpackaged
  • <types>包含元数据类型的名称(对于 示例, ) 和命名成员 (对于 示例,) 进行部署。您可以在清单中添加多个元素 文件。CustomObjectmyCustomObject__c<types>
  • <members>包含组件的 fullName,例如 。对于许多元数据类型,可以将 中的值替换为通配符(星号),而不是单独列出每个成员。为 允许通配符的元数据类型列表,请参阅“允许 “元数据类型”中的通配符 (*)?“ 列。MyCustomObject__cmembers*注意在元素中指定 Security,在名称中指定 Settings 元素。<members>
  • <name>包含元数据类型,例如 或 。目录中的每种元数据类型都定义了一个名称。任何 扩展元数据的元数据类型是 有效值。输入的名称必须与 元数据 API WSDL。有关列表,请参阅元数据类型。CustomObjectProfile
  • <version>是使用的 API 版本号 部署或检索 .zip 文件时。目前 有效值为 。59.0

有关演示如何工作的更多示例包 .xml 清单文件 使用不同的元数据子集,请参阅示例包 .xml 清单 文件。

要删除组件,请参阅从组织中删除组件。

使用 REST 通过 Apex 测试部署元数据

使用 REST 资源部署到 启动处理部署的所有操作的请求。

deployRequest

您可以部署或 一次最多可检索 10,000 个文件。AppExchange 软件包使用不同的限制: 最多可包含 35,000 个文件。已部署或检索的 .zip 的最大大小 文件大小为 39 MB。如果文件在解压缩的文件夹中解压缩,则大小限制 是 400 MB。URIhttps://host/services/data/vXX.0/metadata/deployRequest格式JSON格式HTTP 方法发布认证Authorization: Bearer token

deployOptions 参数

注意

查看可以节省时间的部署和方法的默认测试行为 同时仍使您能够满足测试要求,请参阅在部署中运行测试和在沙盒和生产部署中运行相同的测试。

参数描述
allowMissingFiles布尔。如果 package.xml 中指定的文件不是 在 .zip 文件中,指定部署是否仍可 成功。不要为部署到生产组织设置此参数。
autoUpdatePackage保留以备将来使用。
仅检查布尔。缺省值为 .设置为执行 组件,而不将组件保存在目标组织中。验证使您能够 验证将在部署中生成但未生成的测试结果 提交任何更改。验证完成并通过测试后,它就可以符合条件 用于在不重新运行测试的情况下进行部署。请参阅在不进行测试的情况下部署最近验证的组件集。falsetrue
ignore警告布尔。指示部署是否 尽管有一个或多个警告 () 或不 (),但允许成功完成。缺省值为 .truefalsefalse的 DeployMessage 对象 warning 包含以下值:问题类型—Warningproblem – 警告的文本。如果出现警告,并且 ignoreWarnings 设置为 ,则 success 字段 在 DeployMessage 中是 。如果 ignoreWarnings 设置为 ,则 success 设置为 ,并且警告被视为 错误。truetruefalsefalse
执行检索保留以备将来使用。
purgeOnDelete(清除OnDelete)布尔。如果 ,destructiveChanges.xml 清单文件中已删除的组件不会存储在 回收站。相反,它们会立即符合删除条件。true此选项仅适用于 Developer Edition 或沙盒组织。 它在生产组织中不起作用。
rollbackOnError布尔。指示任何故障是否会导致完全回滚 () 或 ()。如果,无论什么动作都可以 在不执行错误的情况下执行,并返回其余的错误 行动。此参数必须设置为 if 您正在部署到生产组织。缺省值为 。truefalsefalsetruefalse
运行测试字符串 []。要在部署期间运行的 Apex 测试列表。指定类 name,每个实例一个名称。类名还可以指定带有点的命名空间 表示法。有关更多信息,请参见在部署中运行测试的子集。要使用此选项,请将 testLevel 设置为 。RunSpecifiedTests
单包布尔。指示指定的文件是指向具有单个包 () 的目录结构,还是指向一组包 (..ziptruefalse)
testLevelTestLevel(字符串类型的枚举)。自选。指定运行哪些测试 作为部署的一部分。无论类型如何,都会强制执行测试级别 部署包中存在的组件。有效值为:NoTestRun– 不运行任何测试。这 测试级别仅适用于开发环境的部署,例如 沙盒、Developer Edition 或试用组织。此测试级别是 开发环境的默认值。RunSpecifiedTests– 仅运行您在 runTests 选项中指定的测试。代码覆盖率要求 使用此测试级别时,与默认覆盖率要求不同。每 部署包中的类和触发器必须被执行的 测试至少 75% 的代码覆盖率。此覆盖范围是针对每个 类和触发器单独,与整体覆盖范围不同 百分比。RunLocalTests—所有测试在您的 org 运行,但源自 installed managed 和 解锁的包裹。此测试级别是生产环境的默认级别 包含 Apex 类或触发器的部署。RunAllTestsInOrg—所有测试都是 跑。这些测试包括组织中的所有测试,包括托管测试 包。如果未指定测试级别,则默认测试执行行为为 使用。请参阅在部署中运行测试。作为部署的一部分运行的 Apex 测试始终以同步和串行方式运行。

请求正文:部署元数据

部署元数据时,请求包括部署参数和 .zip 包含组件目录和清单的文件。将标头设置为 ,Content-Type: multipart/form-data

此示例 POST 请求创建一个启动部署的对象。deployRequest

  1. POST 请求标头设置为并定义一个值来封装请求的不同子部分。Content-Type: multipart/form-databoundary
  2. 在第一个边界之后的子部分中,JSON 请求创建一个子对象,用于传递部署参数。deployOptions
  3. 第二个边界后面的子部分指定包含清单的 .zip 文件 和组件目录。
POST /services/data/v48.0/metadata/deployRequest
Authorization: Bearer 00D....
Content-Type: multipart/form-data; boundary=--------------------------BOUNDARY
----------------------------BOUNDARY
Content-Disposition: form-data; name="json"
Content-Type: application/json
{ 
    "deployOptions" :
        {
        "allowMissingFiles" : false,
        "autoUpdatePackage" : false,
        "checkOnly" : false,
        "ignoreWarnings" : false,
        "performRetrieve" : false,
        "purgeOnDelete" : false,
        "rollbackOnError" : false,
        "runTests" : null,
        "singlePackage" : true,
        "testLevel" : "RunAllTestsInOrg"
        }
    }
----------------------------BOUNDARY
Content-Disposition: form-data; name="file"; filename="deploy.zip"
Content-Type: application/zip

//Contents of deploy.zip
----------------------------BOUNDARY--

响应正文:部署元数据

当返回 HTTP 状态码 (Created) 时,您的 请求已成功,并导致创建正在处理的部署。201

{ "id" : "0Afxx00000001VPCAY",
  "deployOptions" : 
   { "checkOnly" : false,
     "singlePackage" : false,
     "allowMissingFiles" : false,
     "performRetrieve" : false,
     "autoUpdatePackage" : false,
     "rollbackOnError" : true,
     "ignoreWarnings" : false,
     "purgeOnDelete" : false,
     "runAllTests" : false },
  "deployResult" : 
   { "id" : "0Afxx00000001VPCAY",
     "success" : false,
     "checkOnly" : false,
     "ignoreWarnings" : false,
     "rollbackOnError" : true,
     "status" : "Pending",
     "runTestsEnabled" : false,
     "done" : false } }

deployResult 参数

参数描述
编号ID。正在部署的组件的 ID。
canceled作者ID。取消部署的用户的 ID。
canceledByName字符串。取消部署的用户的全名。
仅检查布尔。指示此部署是否用于检查 在不更改组织的情况下部署的文件 () 或不 ()。仅检查部署不会 部署任何组件或以任何方式更改组织。truefalse
完成日期日期时间。部署过程结束的时间戳。
创建者ID。创建部署的用户的 ID。
createdByName字符串。创建部署的用户的全名。
创建日期日期时间。收到部署请求时的时间戳。
DeployDetails。提供正在进行的部署的详细信息,或者 ended if 添加为 查询到 GET 请求。?includeDetails=true
布尔。指示服务器是否完成了部署请求的处理 对于指定的 ID。
errorMessage (错误消息)字符串。与 errorStatusCode 字段中的值(如果有)相对应的消息。
errorStatusCode字符串。如果在部署请求期间发生错误,则状态代码为 返回,在 errorMessage字段中返回状态码对应的消息。
ignore警告布尔。自选。缺省值为 . 指定即使部署生成警告,部署是否继续。 不要将此参数设置为 for deployments 到生产组织。falsetrue
上一个修改日期日期时间。部署过程上次更新的时间戳。
numberComponentErrors国际部署过程中部署的组件数。使用这个 value 替换为 numberComponentsTotal 值来获取估计值 部署进度。
numberComponentsTotal(数量组件合计)国际部署中的组件总数。将此值与 numberComponentsDeployed 值一起使用可获取 部署进度。
numberTestErrors国际在此期间生成错误的 Apex 测试数 部署。
numberTests已完成此部署已完成的 Apex 测试数。将此值与 numberTestsTotal 值一起使用,可获取部署的 测试进度。
numberTestsTotal国际此部署的 Apex 测试总数。将此值用于 numberTestsCompleted 值来获取 部署的测试进度。此字段中的值在 部署已开始对正在部署的组件运行测试。
runTests已启用布尔。指示 Apex 测试是否作为此部署的一部分运行 () 或不 ()。测试要么作为部署的一部分自动运行,要么 可以设置为在 deployOptions 子对象中运行。truefalse
rollbackOnError布尔。缺省值为 .表明 是否有任何故障导致完全回滚 () 或不 ()。如果 ,可以执行任何一组操作 不执行任何错误,其余操作返回错误。 如果 部署到生产组织。truetruefalsefalsetrue
开始日期日期时间。部署过程开始的时间戳。
状态详细信息字符串。指示正在部署哪个组件或哪个 Apex 测试类 运行。
地位指示部署的当前状态。有效值为:PendingInProgressSucceededSucceededPartialFailedCancelingCanceled
成功布尔。指示部署是否成功 () 或 ()。truefalse

使用 REST 资源检查部署状态

检查部署状态,方法是在 URL 响应正文与原始部署请求返回的响应正文类似,但它 包括有关正在进行的部署的信息。URIhttps://host/services/data/vXX.0/metadata/deployRequest/deployRequestId

自 在响应中包含更多详细信息,请使用:

https://host/services/data/vXX.0/metadata/deployRequest/deployRequestId?includeDetails=true格式JSON格式HTTP 方法获取认证Authorization: Bearer token

响应正文:部署元数据

以下示例显示了作为查询添加到 GET 请求时的响应。?includeDetails=true

{ 
	       "id" : "0Afxx00000000lWCAQ"
	       "url" : "https://host/services/data/vXX.0/metadata/deployRequest/0Afxx00000000lWCAQ?includeDetails=true",
        "deployResult" :
            {
            "checkOnly" : "false",
            "ignoreWarnings" : "false",
            "rollbackOnError" : "false",
            
            "status : "InProgress",
            "numberComponentsDeployed" : "10", 
            "numberComponentsTotal" : "1032",
            "numberComponentErrors" : "0",
            "numberTestsCompleted" : "45",
            "numberTestsTotal" : "135",
            "numberTestErrors" : "0",            
            "details" :  { 
	             "componentFailures" : [],
             	"componentSuccesses" : [],
                    "retrieveResult" : null,
                    "runTestResults" : {
                    "numRun" : 0,
                    "successes" : [ … ],
                    "failures" : []
	         	         }
            },

            "createdDate" : "2017-10-10T08:22Z",       
            "startDate" : "2017-10-10T08:22Z",
            "lastModifiedDate" : "2017-10-10T08:44Z",
            "completedDate" : "2017-10-10T08:44Z",

            "errorStatusCode" : null,
            "errorMessage" : null,
            "stateDetail" : "Processing Type: Apex Component",

            "createdBy" : "005xx0000001Sv1m",
            "createdByName" : "stephanie stevens", 
            "canceledBy" : null,
            "canceledByName" : null,            
            "isRunTestsEnabled" : null
            }

       "deployOptions": {    
             "allowMissingFiles" : false,
             "autoUpdatePackage" : false,
             "checkOnly" : true,
             "ignoreWarnings" : false,
             "performRetrieve" : false,
             "purgeOnDelete" : false,
             "rollbackOnError" : false,
             "runTests" : null,
             "singlePackage" : true,
             "testLevel" : "RunAllTestsInOrg"
             }
     }

预计返回 HTTP 状态代码 (OK)。200

部署最近验证的组件集,无需测试

您可以通过跳过 Apex 的执行,在更短的时间内将组件部署到生产环境 在已经满足测试要求时进行测试。

  • 在过去 10 年中,这些组件已针对目标环境成功验证 日。
  • 作为验证的一部分,目标组织中的 Apex 测试已通过。
  • 满足代码覆盖率要求。
    • 如果运行组织中的所有测试或所有本地测试,则总体代码覆盖率至少为 75%, 和 Apex 触发器有一定的覆盖范围。
    • 如果使用测试级别运行特定测试,则至少覆盖了 75% 的要部署的每个类和触发器 单独。RunSpecifiedTests

此操作等效于在 Salesforce 用户界面中的“部署状态”页面。

要在使用资源时验证但不部署一组组件,请将参数设置为 。记下响应中的部署请求 ID。使用此 ID (与成功的验证相关联)以部署组件集,而无需重复 验证。deployRequestcheckOnlydeployOptionstrueURIhttps://host/services/data/vXX.0/metadata/deployRequest/validatedDeployRequestId格式JSON格式HTTP 方法发布认证Authorization: Bearer token

请求正文:部署最近验证的组件集,无需测试

注意

用于部署最近验证的组件集的 HTTP 方法是 POST,而不是 PATCH。用 PATCH 将创建一个新部署。

{ 
       "validatedDeployRequestId" : "0Afxx00000000lWCAQ"
    }

如果没有满足验证要求的相应部署包,则 接收 HTTP 状态代码 (Not Found)。如果已验证 找到部署包,返回的 HTTP 状态码为 (Created)。404201

响应正文:部署最近验证的组件集,而不进行测试

注意

来自未验证请求的部署的响应正文包括新的请求 ID。 因为它与之前对仅验证部署的请求是分开的。

{ 
       "validatedDeployRequestId" : "0Afxx00000000lWCAQ"
       "id" : "0Afxx00000000lWMEM"
       "url" : "https://host/services/data/vXX.0/metadata/deployRequest/0Afxx00000000lWMEM",
       "deployOptions" :
             {
             "allowMissingFiles" : false,
             "autoUpdatePackage" : false,
             "checkOnly" : true,
             "ignoreWarnings" : false,
             "performRetrieve" : false,
             "purgeOnDelete" : false,
             "rollbackOnError" : false,
             "runTests" : null,
             "singlePackage" : true,
             "testLevel" : "RunAllTestsInOrg"
}
     }

当返回 HTTP 状态码 (Created) 时,您的 请求已成功,并导致创建正在处理的部署。在 在前面的示例响应正文中,仅验证部署请求的 ID 为 ;部署的 ID,不带 验证请求是 。2010Afxx00000000lWCAQ0Afxx00000000lWMEM

使用 REST 取消正在进行的部署

您可以请求取消正在进行的部署。使 通过修补正在进行的 .取消是异步处理的。

deployRequestURIhttps://host/services/data/vXX.0/metadata/deployRequest/deployRequestId格式JSON格式HTTP 方法补丁认证Authorization: Bearer token

请求正文:请求部署取消

部署取消的 JSON 请求正文包括 源语言。deployRequest

{ 
     "deployResult":
           {
           "status" : "Canceling"
           }
    }

响应正文:请求部署取消

由于取消请求是异步处理的,因此响应中显示的状态 body 可以是 或 。CancelingCanceled

{ 
      	"id" : "0Afxx00000000lWCAQ"
      	"url" : “https://host/services/data/vXX.0/metadata/deployRequest/0Afxx00000000lWCAQ",
       "deployResult":    
             {
             "checkOnly" : "false",
             "ignoreWarnings" : "false",
             "rollbackOnError" : "false",             
             "status : "Canceling",  // or Canceled
             "numberComponentsDeployed" : "10",
             "numberComponentsTotal" : "1032",
             "numberComponentErrors" : "0",
             "numberTestsCompleted" : "45",
             "numberTestsTotal" : "135",
             "numberTestErrors" : "0",
             "details" :  { 
                "componentFailures" : [],
                "componentSuccesses" : [],
                      "retrieveResult" : null,
                      "runTestResults” : {
                         "numRun" : 0,
                         "successes" : [ … ],
                         "failures" : []
                 	   	}             
                },

                "createdDate" : "2017-10-10T08:22Z",
                "startDate" : "2017-10-10T08:22Z",
                "lastModifiedDate" : "2017-10-10T08:44Z",
                "completedDate" : "2017-10-10T08:44Z",
                "errorStatusCode" : null,
                "errorMessage" : null,
                "stateDetail" : "Processing Type: Apex Component",
                "createdBy" : "005xx0000001Sv1m",
                "createdByName" : "steve stevens",
                "canceledBy" : null, 
                "canceledByName" : null,
                "isRunTestsEnabled" : null
                }
       }

当返回 HTTP 状态码 (Accepted) 时,您的 取消请求正在进行中或成功。202

在 Salesforce CLI 中使用 REST API 部署元数据

默认情况下,Salesforce CLI 命令使用元数据 SOAP API 将源部署到您的组织。您可以 通过设置 CLI 配置值或环境来改用元数据 REST API 变量。与 SOAP API 相比,REST API 提供了更快的部署速度。

project deploy start

用户 所需权限
要从 Salesforce CLI 使用元数据 API,请执行以下操作:通过元数据 API 函数修改元数据或修改所有数据

使用 Salesforce CLI 运行时配置变量或环境变量,用于将 REST API 设置为 默认值。有关更多信息,请参阅《Salesforce DX 设置指南》。org-metadata-rest-deploySF_ORG_METADATA_REST_DEPLOY

此示例使用配置值来设置当前 项目:

sf config set org-metadata-rest-deploy true

若要为所有项目全局设置默认值,请使用以下标志:–global

sf config set org-metadata-rest-deploy true --global

注意

仅部署源的命令,例如 project deploy start,支持 REST API。检索源的命令(如项目检索启动)始终使用 SOAP API。

以下是部署限制。

特征限制
最大压缩 .zip 文件夹大小1(SOAP API)约39MB
最大未压缩文件夹大小2(SOAP API)约400MB
AppExchange 软件包(REST 和 SOAP)中的最大文件数 API接口)30,000(API 版本 47.0 及更高版本)22,000(API 版本 46.0)17,500(API 版本 45.0)12,500(API 版本 43.0 和 44.0)10,000(API 版本 42.0 及更早版本)
包中的最大文件数(REST 和 SOAP API)10,000

1元数据 API base-64 在压缩组件后对其进行编码。这 生成的 .zip 文件不能超过 50 MB。Base-64 编码增加了 有效负载大约减少 22%,因此压缩的有效负载不能超过大约 编码前为 39 MB。

2使用 Ant 迁移工具部署解压项目时,所有 首先压缩项目中的文件。未压缩的最大大小 未压缩项目中的组件为 400 MB 或更少,具体取决于文件的 压缩比。如果文件的压缩率较高,则可以将 总计约为 400 MB,因为压缩大小将小于 39 MB。 但是,如果组件不能被压缩太多,比如二进制静态资源, 您可以迁移小于 400 MB。

错误处理

元数据 API 调用返回客户端应用程序的错误信息 可用于识别和解决运行时错误。

元数据 API 提供这些类型的错误处理。

  • 由于元数据 API 使用企业或合作伙伴 WSDL 进行身份验证,因此它使用 SOAP 错误 在这些 WSDL 中为格式不正确的消息导致的错误定义的消息, 身份验证失败或类似问题。每个 SOAP 错误都有一个关联的 ExceptionCode。有关详细信息,请参阅《SOAP API 开发人员指南》中的错误处理。
  • 对于异步 create()、update() 和 delete() 调用的错误, 请参阅关联组件的 AsyncResult 对象的 statusCode 字段中的错误状态代码。
  • 有关同步 CRUD 调用的错误,请参阅 Error 对象的 statusCode 字段中的错误状态代码 对应于相应结果对象的 errors 字段返回的数组中的每个错误。例如,createMetadata() 的结果对象是 SaveResult。
  • 对于 deploy() 的错误,请参阅 关联的 DeployMessage 对象中的问题和成功字段 元件。
  • 对于 retrieve() 的错误, 请参阅 RetrieveMessage 对象中的问题字段 对于关联的组件。

有关示例代码,请参阅步骤 3:演练 Java 示例代码。

会话过期的错误处理

当您通过通话登录时,新的客户端会话 开始,并生成相应的唯一会话 ID。会话在以下时间后自动过期 在 Salesforce 应用程序的“Security Controls”设置区域中指定的时间量(默认为 2 小时)。 会话过期时,将返回异常代码INVALID_SESSION_ID。如果发生这种情况, 您必须再次调用该调用。更多信息 关于,请参阅《SOAP API 开发人员指南》。login()login()login()