部署和检索元数据

使用 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()

快速入门:元数据 API

面向初学者开发人员的资源

如果您是初学者开发人员,并且以前没有使用过 Salesforce CLI,请了解如何设置 您的环境和示例应用程序的实践。这些 Trailhead 将引导您完成 使用 SFDX 进行设置,并向您介绍元数据 API。

使用 Salesforce CLI 和源代码管理开发应用程序 登山口

演练使用以下方法设置环境和使用 Salesforce CLI 进行开发 Dreamhouse 示例应用。向 Dreamhouse 应用程序添加功能后,将元数据部署到 使用 Salesforce CLI 的 Dev Hub 组织。

包 .xml 元数据管理

详细了解元数据和包.xml文件。生成包.xml文件以部署更改 从零开始的组织到您的 Trailhead Playground。

使用元数据 API 进行开发的快速入门

如果您在 Salesforce 开发方面有一些经验,但想开始使用元数据 API,请使用此快速入门。本快速入门将引导您完成元数据的检索 组件,这是开发过程的第一步。

  1. 先决条件 在开始使用元数据 API 进行开发之前
    ,请完成这些先决条件。
  2. 步骤 1:(可选)使用 UI
    将元数据组件添加到组织 如果您从没有自定义项的新实践组织开始,则只有无法检索的标准元数据。要使用元数据 API 检索调用,请在 Salesforce UI 上将组件添加到您的实践组织。如果您正在处理现有项目,则已经有要检索的组件,可以跳过此步骤。
  3. 步骤 2:生成包 .xml 清单
    package.xml 清单文件列出了要从组织中检索的组件。
  4. 步骤 3:使用元数据 API
    检索组件 使用 Salesforce CLI,检索包.xml 清单中指定组件的文件表示形式。

先决条件

在开始使用元数据 API 进行开发之前,请完成这些先决条件。

  • 要通过命令行访问元数据 API,请安装 Salesforce CLI。
  • 若要创建开发环境,请注册 适用于 Salesforce 开发人员版。Developer Edition 组织是一个免费开发项目 用于独立于生产数据构建和测试解决方案的环境。
  • 安装适用于 Visual Studio Code 的 Salesforce 扩展。 这些工具提供了与开发组织(临时组织、沙箱、 和 DE orgs)、Apex、Aura 组件和 Visualforce。
  • 确认您拥有“已启用 API”权限,并通过元数据 API 修改元数据 “函数”权限或“修改所有数据”权限。如果您没有这些权限 设置、修改元数据权限。
  • 在组织中启用 Dev Hub。Dev Hub 允许你 创建和管理临时组织,以便在不影响生产数据的情况下进行开发 或元数据。
  • 要允许访问受保护的资源(如生产数据和元数据),请授权您的组织。
  • 在组织中启用 Dev Hub。Dev Hub 允许你 创建和管理临时组织,以便在不影响生产数据的情况下进行开发 或元数据。

步骤 1:(可选) 使用 UI 将元数据组件添加到组织

如果您从没有自定义项的新实践组织开始,则只需 具有无法检索的标准元数据。要使用 Metadata API 检索调用,请添加 组件添加到您的实践组织。如果您正在处理现有项目,则 已有要检索的组件,可以跳过此步骤。

  1. 在“设置”中,单击“创建”。
  2. 选择“自定义对象”。
  3. “标签”(Label) 和“复数标签”(Plural Label) 输入任意名称。
  4. 保存组件。

步骤 2:生成包.xml 清单

package.xml 清单文件列出了要从 组织。

Package.xml 清单结构

package.xml 清单使用可扩展标记语言 (XML) 来标识和迁移 元数据组件。package.xml 清单的基本框架是用元素构建的。元素指定元数据类型 你想与之合作。您可以将多个添加到包.xml文件。<types><types><types>

元素内部是元素和元素。元素 选择特定类型的单个组件,<name> 元素选择 元数据组件类型。要使用特定组件,请在元素中输入该组件的 。<types><name><members><members>fullName<members>

例如,若要检索 Account 组件,请在 package.xml 的元素中添加 Account,并在元素中添加 CustomObject。当您发出检索调用时,您将检索 仅来自您组织的 Account 组件。<members><name>

<?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>

检索自定义对象

若要检索元数据类型的所有组件,请不要指定组件的组件。请改用通配符 *(星号)。一些 组件(如标准对象)不支持 *(星号)作为说明符。fullName<members>

要从您的组织中检索所有自定义对象,请执行以下操作:

  1. (可选)如果您没有项目文件夹,请使用 Salesforce CLI 创建一个 用于组织项目的新目录。使用指定的 楼盘名称:sf project generate –name YourProjectName
  2. 在项目中创建名为 package.xml 的文件。
  3. 在文本编辑器中,打开文件并粘贴以下脚本:
<?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>

现在您有一个 package.xml 文件,我们可以使用它来检索所有自定义对象。什么时候 您可以自己开发更多组件,您可以使用以下命令从您的组织中检索更多组件 多个元素。<types>

步骤 3:使用元数据 API 检索组件

使用 Salesforce CLI,检索 包 .xml 清单。

元数据 API 检索的两个选项

您可以使用以下两个命令之一来检索元数据组件。

  1. 若要检索 package.xml 清单中指定的组件,请发出 使用 Salesforce CLI 命令检索呼叫。在命令行中,运行此调用 替换为适当的文件路径:sf project retrieve start –manifest path/to/package.xml元数据是异步的, 基于文件的命令。您可以发出多个检索或部署请求,这些请求 当资源可用时,它们会自行运行。retrieve()使用此命令,您可以 发送请求以检索 包 .xml 清单。您的请求将排队等待,直到我们的系统准备就绪 处理您的检索调用。在您的请求被取消排队后,您的检索 调用已运行。客户端检查检索的状态并通知您 通话完成后。调用返回 选择的组件。当您使用 Salesforce CLI 发出检索调用时,所有 这些过程是自动化的。该命令允许源跟踪。源 跟踪包括有关您正在处理的修订版的信息,以及 当进行最后一次更改时,这使得源命令更多 对开发人员友好。要使用源跟踪,请确保在 组织。project retrieve start
  2. 或者,在终端中运行以下命令:sf project retrieve start –manifest path/to/package.xml –target-metadata-dir path/to/retrieve/dir此命令 以 MDAPI 格式(而不是源格式)检索组件,并且不会 允许源跟踪。在实践中,管理员更频繁地使用 mdapi 命令 因为这些命令不包括源跟踪。

为元数据 API 构建客户端应用程序

使用元数据 API 检索、部署、创建、更新或删除 组织的自定义项。最常见的用途是从 沙盒或测试组织添加到您的生产环境。元数据 API 适用于 管理自定义项和构建可以管理元数据模型的工具, 而不是数据本身。

Salesforce CLI 自动执行元数据 API 的基础调用。但是,您可以使用这些 直接使用您自己的客户端应用程序进行调用。本指南为您提供了所有信息 require 开始编写直接使用元数据 API 来管理自定义项的应用程序 为您的组织。它向您展示了如何开始使用基于文件的开发。为 基于 CRUD 的开发示例,请参阅 Java 基于 CRUD 的开发示例 同步调用。

先决条件

在开始使用元数据 API 之前,请确保完成这些先决条件。

  • 创建开发环境。我们强烈建议您使用沙盒,它是 生产组织。企业版、无限制版和性能版随附 免费的开发者沙盒。有关详细信息,请参阅 http://www.salesforce.com/platform/cloud-infrastructure/sandbox.jsp。或者,您可以使用 Developer Edition (DE) 组织。DE 组织提供对 Enterprise Edition 提供的所有功能,但受用户数量限制 以及存储空间的大小。DE 组织不是生产组织的副本/它提供了一个 您可以在其中构建和测试解决方案而不会影响 组织的数据。Developer Edition 帐户可在 https://developer.salesforce.com/signup 免费获得。
  • 标识具有“已启用 API”权限和“修改元数据”的用户 元数据 API 函数权限或修改所有数据权限。这些权限是 需要访问元数据 API 调用。注意如果用户需要访问元数据,但不需要 data,请启用“通过元数据 API 函数修改元数据”权限。否则 启用“修改所有数据”权限。
  • 安装 SOAP 客户机。元数据 API 适用于当前的 SOAP 开发环境, 包括但不限于 Visual Studio® .NET 和 Web 服务连接器 (WSC)。在本文档中,我们提供了基于 WSC 和 JDK 6(Java 平台)的 Java 示例 标准版开发套件 6)。若要运行示例,请先下载最新的 force-wsc JAR 文件及其依赖项来自 mvnrepository.com/artifact/com.force.api/force-wsc/。列出了依赖项 在选择版本时的页面上。注意开发平台在以下方面各不相同 SOAP 实现。某些开发平台的实现差异可以 阻止访问元数据 API 中的部分或全部功能。

步骤 1:生成或获取 Web 服务 组织的 WSDL

若要访问元数据 API 调用,需要 Web 服务描述语言 (WSDL) 文件。The WSDL file 定义可供您使用的 Web 服务。您的开发平台使用 此 WSDL 生成存根代码以访问它定义的 Web 服务。您可以获取 WSDL 文件(如果有) 访问 Salesforce 用户界面中的 WSDL 下载页面,您可以生成它 你自己。有关 WSDL 的更多信息,请参见 http://www.w3.org/TR/wsdl

在访问元数据 API 调用之前, 您必须通过身份验证才能使用调用来使用 Web 服务,该调用在企业中定义 WSDL 和合作伙伴 WSDL。因此,您还必须获得以下一项 这些 WSDL。login()具有“通过元数据 API 函数修改元数据”或“修改所有数据”权限的任何用户 可以下载 WSDL 文件以集成和扩展 Salesforce 平台。

注意

如果用户需要访问元数据,但不需要 data,请启用“通过元数据 API 函数修改元数据”权限。否则 启用“修改所有数据”权限。

步骤 3:演练 Java 示例代码中的示例代码使用企业 WSDL,但合作伙伴 WSDL 工作 同样好。

要为您的组织生成元数据和企业 WSDL 文件,请执行以下操作:

  1. 登录到您的 Salesforce 帐户。 您必须以管理员或具有“修改 所有数据“权限。
  2. 在“设置”中,输入“快速查找”框,然后选择“API”。API
  3. 单击“生成元数据 WSDL”,并将 XML WSDL 文件保存到您的文件中 系统。
  4. 单击“生成企业 WSDL”,并将 XML WSDL 文件保存到您的文件中 系统。

第 2 步:将 WSDL 文件导入到 开发平台

获得 WSDL 文件后,将它们导入到开发中 平台,以便您的开发环境可以生成必要的 用于生成客户端 Web 服务应用程序的对象。这 部分提供了 WSC 的示例说明。有关以下内容的说明 其他开发平台,请参阅平台的产品文档。

注意

导入 WSDL 文件的过程与元数据相同 和企业 WSDL 文件。

Java 环境说明 (WSC)

Java 环境通过 Java 对象访问 API,这些对象 充当服务器端对应物的代理。在使用 API 之前,您必须 首先从组织的 WSDL 文件生成这些对象。

每个 SOAP 客户端都有自己的工具用于此过程。对于 WSC,请使用 实用程序。wsdlc

注意

在运行 之前,必须在系统上安装并引用 WSC JAR 文件 在您的类路径中。您可以下载最新的 force-wsc JAR 文件 及其依赖项(依赖项在页面上列出时 从 mvnrepository.com/artifact/com.force.api/force-wsc/ 中选择一个版本。wsdlc的基本语法是:

wsdlc

java -classpath pathToWsc;pathToWscDependencies com.sforce.ws.tools.wsdlc pathToWsdl/WsdlFilename pathToOutputJar/OutputJarFilename

例如,在 Windows 上:

java –classpath force-wsc-30.0.0.jar;ST4-4.0.7.jar;antlr-runtime-3.5.jar com.sforce.ws.tools.wsdlc metadata.wsdl metadata.jar

在 Mac OS X 和 Unix 上,使用冒号而不是分号 类路径中的项:

java –classpath force-wsc-30.0.0.jar:ST4-4.0.7.jar:antlr-runtime-3.5.jar com.sforce.ws.tools.wsdlc metadata.wsdl metadata.jar

wsdlc生成 JAR 文件 以及用于创建客户端的 Java 源代码和字节码文件 应用。对企业 WSDL 重复此过程以创建 一个企业。JAR 文件。

步骤 3:演练 Java 示例代码

导入 WSDL 文件后,可以构建使用 元数据 API。此示例是编写自己的代码的良好起点。

在运行示例之前,请修改项目和代码,以便:

  1. 包括 WSC JAR、其依赖项以及您从 WSDL。注意尽管 WSC 具有其他依赖项,但仅以下示例 需要 Rhino (js-1.7R2.jar),您可以从 mvnrepository.com/artifact/rhino/js 下载。
  2. 使用您的用户名和密码更新方法中的 USERNAME 和 PASSWORD 变量。如果 您当前的 IP 地址不在组织的受信任 IP 范围内,您将 需要将安全令牌附加到密码中。MetadataLoginUtil.login()
  3. 如果您使用的是沙盒,请务必更改登录 URL。

登录实用程序

Java 用户可用于连接到 企业、合作伙伴和元数据 SOAP API。 创建对象并使用企业 WSDL 登录名登录 方法。然后,它检索并创建一个并连接到元数据 API 端点。 定义于 WSC。ConnectorConfigMetadataLoginUtilConnectorConfigsessionIdmetadataServerUrlConnectorConfigConnectorConfig

该类抽象化登录名 示例其他部分的代码,允许重用此代码的某些部分 无需更改不同的 Salesforce API。MetadataLoginUtil

import com.sforce.soap.enterprise.EnterpriseConnection;
import com.sforce.soap.enterprise.LoginResult;
import com.sforce.soap.metadata.MetadataConnection;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

/**
 * Login utility.
 */
public class MetadataLoginUtil {

    public static MetadataConnection login() throws ConnectionException {
        final String USERNAME = "user@company.com";
        // This is only a sample. Hard coding passwords in source files is a bad practice.
        final String PASSWORD = "password"; 
        final String URL = "https://login.salesforce.com/services/Soap/c/59.0";
        final LoginResult loginResult = loginToSalesforce(USERNAME, PASSWORD, URL);
        return createMetadataConnection(loginResult);
    }

    private static MetadataConnection createMetadataConnection(
            final LoginResult loginResult) throws ConnectionException {
        final ConnectorConfig config = new ConnectorConfig();
        config.setServiceEndpoint(loginResult.getMetadataServerUrl());
        config.setSessionId(loginResult.getSessionId());
        return new MetadataConnection(config);
    }

    private static LoginResult loginToSalesforce(
            final String username,
            final String password,
            final String loginUrl) throws ConnectionException {
        final ConnectorConfig config = new ConnectorConfig();
        config.setAuthEndpoint(loginUrl);
        config.setServiceEndpoint(loginUrl);
        config.setManualLogin(true);
        return (new EnterpriseConnection(config)).login(username, password);
    }
}

注意

此示例使用用户和密码身份验证来获取会话 ID,该 ID 然后用于调用元数据 API。或者,您可以使用 OAuth 认证。使用 OAuth 向 Salesforce 发送请求后,将返回的 访问令牌,而不是会话 ID。例如,将访问令牌传递给 上的调用。了解如何使用 OAuth 在 Salesforce 中进行身份验证,请参阅使用以下方式对应用程序进行身份验证 Salesforce 帮助中的 OAuth。setSessionId()ConnectorConfig

基于文件的 Java 示例代码 发展

示例代码使用登录实用程序登录。然后它显示一个菜单 检索、部署和退出。

和调用都对名为 components.zip 的 .zip 文件进行操作。该调用将组织中的组件检索到 components.zip 中,并且该调用将 components.zip 中的组件部署到组织。如果保存示例 到您的计算机并执行它,首先运行 retrieve 选项,以便您有一个可以随后部署的组件.zip文件。后 检索调用,示例在循环中调用,直到操作完成。 同样,在部署调用之后,示例会在循环中进行检查,直到操作完成。retrieve()deploy()retrieve()deploy()checkRetrieveStatus()checkDeployStatus()

该调用使用清单文件执行以下操作: 确定要从组织中检索的组件。下面是一个示例包 .xml 清单文件。有关 清单文件结构,请参阅使用 Zip 文件部署和检索元数据。在此示例中,清单文件检索所有自定义对象。 自定义选项卡和页面布局。retrieve()

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

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

注意

此示例需要 API 版本 34.0 或 后。

import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.rmi.RemoteException;
import java.util.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import com.sforce.soap.metadata.*;

/**
 * Sample that logs in and shows a menu of retrieve and deploy metadata options.
 */
public class FileBasedDeployAndRetrieve {

    private MetadataConnection metadataConnection;

    private static final String ZIP_FILE = "components.zip";

    // manifest file that controls which components get retrieved
    private static final String MANIFEST_FILE = "package.xml";

    private static final double API_VERSION = 29.0;

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

    // maximum number of attempts to deploy the zip file
    private static final int MAX_NUM_POLL_REQUESTS = 50;

    private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws Exception {
        FileBasedDeployAndRetrieve sample = new FileBasedDeployAndRetrieve();
        sample.run();
    }

    public FileBasedDeployAndRetrieve() {
    }

    private void run() throws Exception {
        this.metadataConnection = MetadataLoginUtil.login();

        // Show the options to retrieve or deploy until user exits
        String choice = getUsersChoice();
        while (choice != null && !choice.equals("99")) {
            if (choice.equals("1")) {
                retrieveZip();
            } else if (choice.equals("2")) {
                deployZip();
            } else {
                break;
            }
            // show the options again
            choice = getUsersChoice();
        }
    }

    /*
     * Utility method to present options to retrieve or deploy.
     */
    private String getUsersChoice() throws IOException {
        System.out.println(" 1: Retrieve");
        System.out.println(" 2: Deploy");
        System.out.println("99: Exit");
        System.out.println();
        System.out.print("Enter 1 to retrieve, 2 to deploy, or 99 to exit: ");
        // wait for the user input.
        String choice = reader.readLine();
        return choice != null ? choice.trim() : "";
    }

    private void deployZip() throws Exception {
        byte zipBytes[] = readZipFile();
        DeployOptions deployOptions = new DeployOptions();
        deployOptions.setPerformRetrieve(false);
        deployOptions.setRollbackOnError(true);
        AsyncResult asyncResult = metadataConnection.deploy(zipBytes, deployOptions);
        DeployResult result = waitForDeployCompletion(asyncResult.getId());
        if (!result.isSuccess()) {
            printErrors(result, "Final list of failures:\n");
            throw new Exception("The files were not successfully deployed");
        }
        System.out.println("The file " + ZIP_FILE + " was successfully deployed\n");
    }

    /*
    * Read the zip file contents into a byte array.
    */
    private byte[] readZipFile() throws Exception {
        byte[] result = null;
        // We assume here that you have a deploy.zip file.
        // See the retrieve sample for how to retrieve a zip file.
        File zipFile = new File(ZIP_FILE);
        if (!zipFile.exists() || !zipFile.isFile()) {
            throw new Exception("Cannot find the zip file for deploy() on path:"
                + zipFile.getAbsolutePath());
        }

        FileInputStream fileInputStream = new FileInputStream(zipFile);
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead = 0;
            while (-1 != (bytesRead = fileInputStream.read(buffer))) {
                bos.write(buffer, 0, bytesRead);
            }

            result = bos.toByteArray();
        } finally {
            fileInputStream.close();
        }
        return result;
    }

    /*
    * Print out any errors, if any, related to the deploy.
    * @param result - DeployResult
    */
    private void printErrors(DeployResult result, String messageHeader) {
        DeployDetails details = result.getDetails();
        StringBuilder stringBuilder = new StringBuilder();
        if (details != null) {
            DeployMessage[] componentFailures = details.getComponentFailures();
            for (DeployMessage failure : componentFailures) {
                String loc = "(" + failure.getLineNumber() + ", " + failure.getColumnNumber();
                if (loc.length() == 0 && !failure.getFileName().equals(failure.getFullName()))
                {
                    loc = "(" + failure.getFullName() + ")";
                }
                stringBuilder.append(failure.getFileName() + loc + ":" 
                    + failure.getProblem()).append('\n');
            }
            RunTestsResult rtr = details.getRunTestResult();
            if (rtr.getFailures() != null) {
                for (RunTestFailure failure : rtr.getFailures()) {
                    String n = (failure.getNamespace() == null ? "" :
                        (failure.getNamespace() + ".")) + failure.getName();
                    stringBuilder.append("Test failure, method: " + n + "." +
                            failure.getMethodName() + " -- " + failure.getMessage() + 
                            " stack " + failure.getStackTrace() + "\n\n");
                }
            }
            if (rtr.getCodeCoverageWarnings() != null) {
                for (CodeCoverageWarning ccw : rtr.getCodeCoverageWarnings()) {
                    stringBuilder.append("Code coverage issue");
                    if (ccw.getName() != null) {
                        String n = (ccw.getNamespace() == null ? "" :
                        (ccw.getNamespace() + ".")) + ccw.getName();
                        stringBuilder.append(", class: " + n);
                    }
                    stringBuilder.append(" -- " + ccw.getMessage() + "\n");
                }
            }
        }
        if (stringBuilder.length() > 0) {
            stringBuilder.insert(0, messageHeader);
            System.out.println(stringBuilder.toString());
        }
    }
    

    private void retrieveZip() throws Exception {
        RetrieveRequest retrieveRequest = new RetrieveRequest();
        // The version in package.xml overrides the version in RetrieveRequest
        retrieveRequest.setApiVersion(API_VERSION);
        setUnpackaged(retrieveRequest);

        AsyncResult asyncResult = metadataConnection.retrieve(retrieveRequest);
        RetrieveResult result = waitForRetrieveCompletion(asyncResult);

        if (result.getStatus() == RetrieveStatus.Failed) {
            throw new Exception(result.getErrorStatusCode() + " msg: " +
                    result.getErrorMessage());
        } else if (result.getStatus() == RetrieveStatus.Succeeded) {  
	        // Print out any warning messages
	        StringBuilder stringBuilder = new StringBuilder();
	        if (result.getMessages() != null) {
	            for (RetrieveMessage rm : result.getMessages()) {
	                stringBuilder.append(rm.getFileName() + " - " + rm.getProblem() + "\n");
	            }
	        }
	        if (stringBuilder.length() > 0) {
	            System.out.println("Retrieve warnings:\n" + stringBuilder);
	        }
	
	        System.out.println("Writing results to zip file");
	        File resultsFile = new File(ZIP_FILE);
	        FileOutputStream os = new FileOutputStream(resultsFile);
	
	        try {
	            os.write(result.getZipFile());
	        } finally {
	            os.close();
	        }
        }
    }

    private DeployResult waitForDeployCompletion(String asyncResultId) throws Exception {
        int poll = 0;
        long waitTimeMilliSecs = ONE_SECOND;
        DeployResult deployResult;
        boolean fetchDetails;
        do {
            Thread.sleep(waitTimeMilliSecs);
            // double the wait time for the next iteration

            waitTimeMilliSecs *= 2;
            if (poll++ > MAX_NUM_POLL_REQUESTS) {
                throw new Exception(
                    "Request timed out. If this is a large set of metadata components, " +
                    "ensure that MAX_NUM_POLL_REQUESTS is sufficient.");
            }
            // Fetch in-progress details once for every 3 polls
            fetchDetails = (poll % 3 == 0);

            deployResult = metadataConnection.checkDeployStatus(asyncResultId, fetchDetails);
            System.out.println("Status is: " + deployResult.getStatus());
            if (!deployResult.isDone() && fetchDetails) {
                printErrors(deployResult, "Failures for deployment in progress:\n");
            }
        }
        while (!deployResult.isDone());

        if (!deployResult.isSuccess() && deployResult.getErrorStatusCode() != null) {
            throw new Exception(deployResult.getErrorStatusCode() + " msg: " +
                    deployResult.getErrorMessage());
        }
        
        if (!fetchDetails) {
            // Get the final result with details if we didn't do it in the last attempt.
            deployResult = metadataConnection.checkDeployStatus(asyncResultId, true);
        }
        
        return deployResult;
    }

    private RetrieveResult waitForRetrieveCompletion(AsyncResult asyncResult) throws Exception {
    	// Wait for the retrieve to complete
        int poll = 0;
        long waitTimeMilliSecs = ONE_SECOND;
        String asyncResultId = asyncResult.getId();
        RetrieveResult result = null;
        do {
            Thread.sleep(waitTimeMilliSecs);
            // Double the wait time for the next iteration
            waitTimeMilliSecs *= 2;
            if (poll++ > MAX_NUM_POLL_REQUESTS) {
                throw new Exception("Request timed out.  If this is a large set " +
                "of metadata components, check that the time allowed " +
                "by MAX_NUM_POLL_REQUESTS is sufficient.");
            }
            result = metadataConnection.checkRetrieveStatus(
                    asyncResultId, true);
            System.out.println("Retrieve Status: " + result.getStatus());
        } while (!result.isDone());         

        return result;
    }

    private void setUnpackaged(RetrieveRequest request) throws Exception {
        // Edit the path, if necessary, if your package.xml file is located elsewhere
        File unpackedManifest = new File(MANIFEST_FILE);
        System.out.println("Manifest file: " + unpackedManifest.getAbsolutePath());

        if (!unpackedManifest.exists() || !unpackedManifest.isFile()) {
            throw new Exception("Should provide a valid retrieve manifest " +
                "for unpackaged content. Looking for " +
                unpackedManifest.getAbsolutePath());
        }

        // Note that we use the fully quualified class name because
        // of a collision with the java.lang.Package class
        com.sforce.soap.metadata.Package p = parsePackageManifest(unpackedManifest);
        request.setUnpackaged(p);
    }

    private com.sforce.soap.metadata.Package parsePackageManifest(File file)
            throws ParserConfigurationException, IOException, SAXException {
        com.sforce.soap.metadata.Package packageManifest = null;
        List<PackageTypeMembers> listPackageTypes = new ArrayList<PackageTypeMembers>();
        DocumentBuilder db =
                DocumentBuilderFactory.newInstance().newDocumentBuilder();
        InputStream inputStream = new FileInputStream(file);
        Element d = db.parse(inputStream).getDocumentElement();
        for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling()) {
            if (c instanceof Element) {
                Element ce = (Element) c;
                NodeList nodeList = ce.getElementsByTagName("name");
                if (nodeList.getLength() == 0) {
                    continue;
                }
                String name = nodeList.item(0).getTextContent();
                NodeList m = ce.getElementsByTagName("members");
                List<String> members = new ArrayList<String>();
                for (int i = 0; i < m.getLength(); i++) {
                    Node mm = m.item(i);
                    members.add(mm.getTextContent());
                }
                PackageTypeMembers packageTypes = new PackageTypeMembers();
                packageTypes.setName(name);
                packageTypes.setMembers(members.toArray(new String[members.size()]));
                listPackageTypes.add(packageTypes);
            }
        }
        packageManifest = new com.sforce.soap.metadata.Package();
        PackageTypeMembers[] packageTypesArray =
                new PackageTypeMembers[listPackageTypes.size()];
        packageManifest.setTypes(listPackageTypes.toArray(packageTypesArray));
        packageManifest.setVersion(API_VERSION + "");
        return packageManifest;
    }
}

元数据 API 开发人员指南

Salesforce 元数据

元数据是描述其他数据的数据。要了解 Salesforce 如何定义元数据, 将业务数据与 Salesforce 元数据进行对比。业务数据包括以下记录: 直接对应于您公司的业务,例如地址、帐户或产品。 Salesforce 元数据描述了架构、流程、表示、授权和常规 Salesforce 组织的配置。

要将 Salesforce 元数据与业务数据进行对比,请首先检查架构元数据的 描述业务数据的属性。例如,Salesforce 标准对象 Address 具有架构元数据和业务数据。 地址字段(如 、 和 )都是架构元数据。每个中的相应值 字段,例如邮寄地址、伊利诺伊州芝加哥和 60106,都是数据。 而个人 身份信息 (PII) 通常存在于业务数据中,元数据还可以包括 PII,例如自定义对象名称、报告名称等。Address TypeCityPostal Code

Salesforce 中的元数据还定义了组织的运作方式。例如,流程元数据 描述当用户按下“保存”按钮时发生的情况。演示文稿元数据问题 组织的布局和授权元数据决定了用户访问权限。Salesforce的 元数据还描述了组织的常规配置。例如,您可以配置 Chatter 阻止帖子中的表情符号。

元数据 API 适用于元数据类型和组件。元数据类型定义 应用程序元数据的结构。元数据组件是元数据类型的实例。 元数据类型的字段和值都是元数据。例如,元数据类型 CustomTab 表示显示内容的自定义选项卡。这 CustomTab 字段指示选项卡是否位于侧边栏面板上, 这是元数据确定表示的一个示例。元数据类型,如 CustomTab 构建元数据模型,描述组织的结构、显示或功能。 使用元数据 API 开发自定义项并构建用于管理元数据模型的工具, 而不是数据本身。hasSidebar

元数据 API 功能

元数据 API 的主要目的是在 Salesforce 组织在开发过程中。使用元数据 API 进行部署、检索、 创建、更新或删除自定义信息,例如自定义对象定义和 页面布局。元数据 API 不直接处理业务数据。要创建, 检索、更新或删除记录,例如客户或潜在客户,使用 SOAP API 或 REST API。

您可以使用以下两种方式之一移动元数据。第一种方法是使用元数据 API 和调用。管理员通常使用 and 调用来移动完整的元数据模型。这些调用 最适合开发的最后阶段,例如将经过测试的自定义项部署到 生产组织。deploy()retrieve()deploy()retrieve()

第二种方法是源推送和拉取命令,这些命令仅移动元数据中的更改。 这些命令使用源跟踪,这使得它们对开发人员更友好,也更好 用于中间开发阶段。

元数据 API 的用例

在开发过程中,使用元数据 API 在组织之间移动元数据 周期。元数据 API 还用于从 发展。

要了解如何使用元数据 API,假设您是 Zephyrus 的 Salesforce 开发人员 搬迁服务。Zephyrus 是一家人才流动公司,帮助公司开发流程 用于国内和国际员工搬迁。Zephyrus 正在向亚洲和南部扩张 美国,并希望为这两个地区增加定向服务。迎新服务包括 在住房和学校搜索、地区旅游和交通方面提供国内援助 信息。

您的开发团队必须将这些新的定向服务添加到其现有组织中。产品 例如,国内方向是可以在 Salesforce 中自定义的对象。当您添加 对象并自定义您的组织,您可以更改其元数据。创建 自定义产品是元数据 API 可以提供帮助的地方。

在开发过程中使用元数据 API

目前,Zephyrus 拥有为其他 国家。若要开始构建新产品自定义项,需要现有的 Zephyrus 生产 Salesforce 组织中的配置位于单独的存储库中。这 生产组织的配置都是元数据。要将生产元数据保存在 存储库,将元数据从 Zephyrus 生产组织移动到本地文件系统。

将元数据从生产环境移动到本地文件系统

在不进行开发更改的情况下进行开发更改 影响现有配置,请使用元数据 API 将元数据移动到本地文件 系统。接下来,将元数据从本地文件系统推送到可共享的存储库,以便 发展。

检索到所有 Zephyrus 元数据后,您可以在本地或临时组织中进行开发。抓 组织是没有数据的一次性 Salesforce 环境。许多开发人员同时使用这两种工具 一起。在本地加载文件和进行更改比在临时执行要快得多 组织。开发人员通常在其本地文件系统上构建自定义项,并在临时运行测试 组织。在测试和开发时,在本地文件系统和临时组织之间移动更改。

将元数据更改移入和移出临时组织

您可以使用临时组织 使用本地文件系统来开发和测试对元数据的更改。要移动更改,请执行以下操作 在本地与 scratch 组织进行本地创建,使用元数据 API。

Zephyrus 开发团队的其他成员都有自己的自定义项。在开发和 您可以自行测试,现在是团队集成更改并在沙盒中运行测试的时候了。 沙盒是用于开发和测试集成的开发环境。

将元数据移动到集成点的沙盒

在开发过程中,使用元数据 用于将元数据移动到沙盒的 API,用于集成更改、测试和协作 团队。

在团队构建定向服务自定义并完成测试后,部署 这些组件使用元数据 API 进行生产。

将元数据部署到生产环境

在最后一步 开发周期,将自定义项从源代码管理系统(如 Git)移动到生产环境 使用元数据 API。

其他用例

您可以使用元数据 API 在 Salesforce 中进行较大的更改,例如拆分和合并 生产组织。

例如,Zephyrus 希望将公司拆分为两个部门,一个部门专门从事 国内搬迁和另一个国际搬迁。在这种情况下,您拆分了 Zephyrus 的 Salesforce 组织并决定哪些元数据属于哪个组织。元数据 API 可以将元数据移动到 新组织。

然后,假设 Zephyrus 收购了 Apollo Global Relocation,两家公司都使用 Salesforce。 要整合信息,您可以使用元数据 API 将 Apollo 组织合并到 Zephyrus 中 组织。

移动生产级更改的元数据

使用元数据 API 移动元数据 在大型更改期间,例如合并或拆分 Salesforce 组织。

您可以使用元数据 API 在开发过程中进行配置更改,这些更改是 对于其他 API 调用来说太大。例如,Zephyrus 支持多种语言,因为它们 全球客户。要为对象翻译不同的语言,请包含一个对象 每种语言的翻译文件。

进行大型元数据配置更改

元数据更适合 用于向组织部署大型更改的其他 API。

将元数据从生产环境移动到本地文件系统

在不影响现有 配置,请使用元数据 API 将元数据移动到本地文件系统。接下来,推送 元数据从本地文件系统传输到可共享的存储库,用于 发展。

在 Salesforce 上构建自定义项时,必须保留 开发周期中的现有组织。若要在不影响自定义项的情况下构建自定义项,请执行以下操作 生产组织,将生产元数据保存在版本控制系统中。Git 集成最好 使用 SFDX 工具。

首先,将所需的元数据从生产组织移动到本地文件系统。移动 元数据到本地计算机,请使用检索调用而不是源拉取。接下来,推动你的 文件复制到团队成员可通过 Git 命令访问的存储库中。这 存储库现在是团队开发的生产元数据的原始来源 周期。

现在,您的生产元数据已存储在存储库中,请将必要的元数据移回 到本地文件系统以开始开发工作。

将元数据更改移入和移出临时组织

使用临时组织来开发和测试对元数据的更改。您可以 使用 Salesforce CLI 或 Salesforce 在临时组织内部或外部执行开发 VS Code 的扩展,利用元数据 API 的强大功能。

临时组织是空的,以便开发人员可以指定确切的元数据和数据 从源代码管理系统中包含。临时组织的生命周期在 创建,1-30 天。它们是短暂的,以确保真相的来源始终是来源 控制系统,而不是组织本身。

您可以使用 Salesforce 将元数据从源代码管理系统或临时组织移动到临时组织 由于临时组织使用源跟踪来识别更改,因此 CLI 是最 在本地存储库和临时组织之间移动元数据的有效方法。继续 遍历在本地文件系统和 暂存组织,直到开发完成。

将元数据移动到集成点的沙盒

在开发过程中,使用元数据 API 将元数据移动到沙盒 集成更改、测试并与您的团队协作。

在临时组织或本地文件系统中自行开发后,将 团队在沙盒中的集成点。沙盒是您可以使用的开发环境 集成和测试来自多个开发人员的更改。管理员通常会创建和分配沙盒。 要在 Salesforce UI 上创建沙盒,请导航到设置。接下来,在“快速查找”框中,搜索 用于沙盒。

您有多个级别的沙盒可供选择,其中包含不同的数据量。这 Developer Sandbox 和 Developer Pro Sandbox 是用于构建的开发环境 对虚构数据进行自定义和测试更改。“部分复制”沙箱和“完整”沙箱是 加载了生产数据副本的测试环境。将元数据移动到不同的沙盒 使用元数据 API 部署命令,具体取决于您的开发和测试需求。

在元数据 API 之外,管理员通常使用更改集从一个 沙盒到另一个。与元数据 API 调用不同,您必须手动构建更改集。要添加 组件到持续集成系统中更容易,您可以自动执行元数据 API 调用 Salesforce 命令行界面。

将元数据部署到生产环境

在开发周期的最后一步中,将自定义项从 源代码控制系统(如 Git)使用元数据 API 投入生产。

当您的团队完成集成测试并准备好部署到生产环境时,请将 完成从本地环境到存储库的自定义。对于版本,请移动 通过将更新的存储库拉回本地,将元数据从存储库拉回生产环境 环境。接下来,使用元数据 API deploy 将元数据部署到生产环境 叫。

将元数据移动到生产环境需要部署调用而不是推送命令,因为 deploy 调用部署整个元数据模型,而不仅仅是元数据中的更改。

部署最近的验证

常规部署调用会执行可能需要很长时间才能完成的自动化 Apex 测试。自 跳过已验证组件的测试并快速将组件部署到生产环境,使用 Deploy 最近的验证选项。

移动生产级更改的元数据

使用元数据 API 在大型更改期间移动元数据,例如 合并或拆分 Salesforce 组织。

要拆分组织,请先检索要移动的元数据。然后,使用 deploy 调用 将这些配置推送到新组织。同样,要合并两个组织,请检索 来自一个组织的现有元数据。接下来,使用 deploy 调用将元数据从 一个组织到另一个组织。

进行大型元数据配置更改

元数据 API 比其他 API 更适合部署大型 对 Salesforce 组织的更改。

元数据 API 和调用是基于文件的,因此 异步。使用同步命令时,大型配置更改需要 加载时间过长。相反,部署和检索调用会以异步方式开始 完成时通知您的流程。由于基于文件的调用是异步的, 元数据 API 还可以处理部署请求队列。deploy()retrieve()

元数据 API 发行说明

使用 Salesforce 发行说明了解 元数据 API。

有关影响 Salesforce Platform 的更新和更改,包括元数据 API,请参阅 API 发行说明。

有关新的、已更改的和已弃用的元数据类型以及特定于元数据 API 的其他更改,请参阅 Salesforce 发行说明中的元数据 API。

元数据 API 开发人员工具

在 Salesforce CLI 上使用适用于 Visual Studio Code 的 Salesforce 扩展访问元数据 API 命令。Salesforce CLI 和 Salesforce Extensions for Visual Studio Code 简化了 使用元数据 API 的过程。访问元数据中功能的最简单方法 API 是使用 Salesforce Extensions for Visual Studio Code 或 Salesforce 这两个工具都建立在元数据 API 之上,并使用标准工具来 简化元数据 API 的使用。

  • 适用于 Visual Studio Code 的 Salesforce 扩展包括以下工具: 在 Salesforce 平台上使用轻量级、可扩展的 VS Code 进行开发 编辑 器。这些工具提供了与开发组织合作的功能 (临时组织、沙盒和 DE 组织)、Apex、Aura 组件和 视觉力。
  • 如果您使用脚本或命令行,Salesforce CLI 是理想的选择 在本地目录和 Salesforce 之间移动元数据 组织。

有关 Salesforce Extensions for Visual 的更多信息 Studio Code 或 Salesforce CLI,请参阅 Salesforce 工具和工具包。

如果您更喜欢构建自己的客户端应用程序,则 Metadata API 的基础调用 已公开供您直接使用。本指南为您提供有关工作的更多信息 直接使用元数据 API。

您可以使用元数据 API 来管理设置和自定义信息(元数据) Salesforce的。例如:

  • 将自定义项导出为 XML 元数据文件。请参阅使用 Zip 文件和 retrieve()。
  • 在组织之间迁移配置更改。参见 deploy() 和 retrieve()。
  • 使用 XML 元数据文件修改现有自定义项。参见 deploy() 和 retrieve()。
  • 以编程方式管理自定义项。请参阅基于 CRUD 的元数据开发。

您可以在 Developer Edition 或沙箱中修改测试组织中的元数据,然后进行部署 测试了对 Enterprise、Unlimited 或 Performance Edition 中生产组织的更改。您可以 此外,还可以创建脚本,以使用自定义对象、自定义字段和其他对象填充新组织 组件。

支持的 Salesforce 版本

若要使用元数据 API,您的组织必须使用 Enterprise Edition, Unlimited Edition、Performance Edition 或 Developer Edition。如果您是现有 想要升级到 Enterprise、Unlimited 或 Performance Edition 的 Salesforce 客户, 请联系您的客户代表。

我们强烈建议您使用沙盒,它是 生产组织。企业版、无限制版和性能版随附 免费的开发者沙盒。有关详细信息,请参阅 http://www.salesforce.com/platform/cloud-infrastructure/sandbox.jsp。

或者,您可以使用 Developer Edition (DE) 组织。DE 组织提供对 Enterprise Edition 提供的所有功能,但受用户数量限制 以及存储空间的大小。DE 组织不是生产组织的副本/它提供了一个 您可以在其中构建和测试解决方案而不会影响 组织的数据。Developer Edition 帐户可在 https://developer.salesforce.com/signup 免费获得。

注意

元数据组件必须在组织中可见,元数据 API 才能对其执行操作。此外,一个 用户必须具有 API Enabled 权限才能访问元数据组件。

专业版元数据 API 访问

ISV 合作伙伴可以请求对 Professional Edition 组织的元数据 API 访问权限,这些应用程序具有以下特点 已通过 AppExchange 安全审核。访问权限是通过 API 令牌(客户端 ID)授予的。 此特殊密钥使应用程序能够向客户的 Professional 进行元数据 API 调用 版本组织。

作为 ISV 合作伙伴,可以按照以下步骤请求元数据 API 访问权限。

  1. 提交您的应用进行安全审核。请参阅安全性中的步骤 在 ISVForce 中查看 指南。
  2. 在您的应用程序获得批准后,在合作伙伴社区中的 AppExchange 和功能请求 |API 令牌请求,并为令牌类型指定 SOAP。

若要调用元数据 API,请在调用中将 API 令牌追加到 CallOptions SOAP 标头。

元数据 API 编辑访问权限

要使用元数据 API,用户必须具备以下条件。

  • 以下版本之一:企业版、无限制版或开发人员版
  • “通过元数据 API 函数修改元数据”或“修改所有数据”权限
  • 允许使用他们想要的元数据所支持的功能的权限 修改
  • 启用其部署工具(例如 Salesforce CLI、更改集或 蚂蚁迁移工具

通过元数据 API 函数修改元数据权限,用户可以访问和编辑 元数据通过元数据 API,只要用户具有访问所需的任何其他权限 某些元数据类型。此附加权限信息列在元数据中 每种元数据类型的 API 开发人员指南。具有“修改所有数据”权限的用户 可以访问和编辑所有数据。

“通过元数据 API 函数修改元数据”权限不影响直接 使用设置 UI 页面自定义元数据,因为这些页面不使用元数据 API 更新。

某些元数据(如 Apex)在系统上下文中执行,因此请注意如何委派 通过元数据 API 函数权限修改元数据。通过元数据修改元数据 API 函数权限允许部署 Apex 元数据,但不允许某些 Apex 仍需要“修改所有数据”权限的开发和调试功能。

在以下情况下,将自动启用“通过元数据 API 函数修改元数据”权限 选择“部署更改集”或“创作 Apex”权限。

当“管理提示”用户权限和“通过元数据修改元数据”API 函数时 权限组合在一起,用户可以在 Lightning Experience 中管理应用程序内指导。

开发平台

元数据 API 支持基于文件和基于 CRUD 的开发。

基于文件的开发

声明性或基于文件的异步元数据 API deploy() 和 retrieve() 操作 部署或检索包含组件的文件 一组文件夹和一个名为 package.xml 的清单文件。查看更多 信息,请参阅部署和检索 元数据。访问基于文件的功能的最简单方法是使用 适用于 Visual Studio Code 的 Salesforce 扩展或 Ant 迁移工具。.zip

基于 CRUD 的开发

CRUD 元数据 API 调用作用于元数据组件 其方式类似于企业 WSDL 中同步 API 调用的行为方式 在对象上。有关企业 WSDL 的更多信息,请参见《SOAP API 开发人员指南》。

标准符合性

元数据 API 的实现符合以下规范:

标准名称网站
简单对象访问协议 (SOAP) 1.1http://www.w3.org/TR/2000/NOTE-SOAP-20000508/
Web 服务描述语言 (WSDL) 1.1http://www.w3.org/TR/2001/NOTE-wsdl-20010315
WS-I 基本概要文件 1.1http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html

元数据 API 支持策略

Salesforce 支持以前版本的元数据 API。但是,您的新客户端应用程序 应使用最新版本的 Lightning 平台元数据 API WSDL 文件,以完全 利用更丰富的功能和更高的效率。

向后兼容性

Salesforce 努力使使用 Lightning 平台时的向后兼容性变得容易。

每个新的 Salesforce 版本都由两个组件组成:

  • 驻留在 Salesforce 系统上的平台软件的新版本
  • API 的新版本

例如,Spring ’07 版本包括 API 版本 9.0 和 Summer ’07 版本 包括 API 版本 10.0。

我们维护对平台软件各个版本的每个 API 版本的支持。该 API 是 向后兼容,因为为使用给定 API 版本而创建的应用程序将 在将来的平台软件版本中继续使用相同的 API 版本。

Salesforce 不保证针对一个 API 版本编写的应用程序能够正常工作 对于未来的 API 版本:方法签名和数据表示形式的更改通常是 当我们继续增强 API 时,需要。但是,我们努力使 API 保持一致,以免 版本到版本,将应用程序移植到较新的 API 所需的更改(如果有)最少 版本。

例如,使用 Spring 附带的 API 版本 9.0 编写的应用程序 ’07 版本,将继续在 Summer ’07 版本上使用 API 版本 9.0, 以及以后的版本。但是,同一应用程序可能无法与 API 一起使用 版本 10.0,无需对应用程序进行修改。

API 生命周期终止政策

查看支持、不支持的元数据 REST 和 SOAP API 版本,或者 不能利用的。

Salesforce 承诺支持每个 API 版本至少 3 个 自首次发布之日起的年。为了提高质量和性能 API,有时不再支持超过 3 年的版本。

Salesforce 通知使用计划的 API 版本的客户 为 折旧 至少 1 年后,对版本的支持将结束。

Salesforce API 版本版本支持状态版本停用信息
版本 31.0 至 59.0支持。
版本 21.0 至 30.0截至 22 年夏季,这些版本已被弃用,并且没有 Salesforce 支持的时间更长。从 25 年夏季开始,这些 版本将停用且不可用。Salesforce Platform API 版本 21.0 到 30.0 停用
版本 7.0 至 20.0自 22 年夏季起,这些版本已停用,并且 不能利用的。Salesforce Platform API 版本 7.0 到 20.0 停用

如果你 请求任何资源或使用已停用的 API 版本 REST API 中的操作 返回错误代码。410:GONE

如果您要求任何 资源或使用已停用的 API 版本中的操作,SOAP API 将返回错误代码。500:UNSUPPORTED_API_VERSION

识别 从旧的或不受支持的 API 版本发出的请求,请使用 API 总使用量事件类型。

相关资源

Salesforce 开发人员网站提供一整套开发人员工具包、示例代码、示例 SOAP 消息、基于社区的支持和其他资源可帮助您进行开发 项目。请务必访问 https://developer.salesforce.com/page/Getting_Started 了解更多信息 信息,或访问 https://developer.salesforce.com/signup 注册一个免费的 Developer Edition 帐户。

您可以访问以下网站以了解有关 Salesforce 应用程序的更多信息:

  • Salesforce 开发人员提供有用的信息 开发 人员。
  • Salesforce 用于 有关 Salesforce 应用程序的信息。
  • 闪电平台 AppExchange,用于访问为 Salesforce 创建的应用程序。
  • 开拓者 社区提供服务,以确保 Salesforce 客户取得成功。

使用最近查看的信息

本节中的示例使用 REST API 查询和最近查看的资源以编程方式检索和更新最近查看的记录 信息。

  • 查看最近查看的记录
    使用“最近查看的项目”资源可获取最近查看的记录列表。
  • 将记录标记为最近查看
    若要使用 REST API 将记录标记为最近查看,请使用带有 or 子句的 Query 资源。使用 SOQL 将记录标记为最近查看,以确保正确设置了记录的日期和时间等信息。FOR VIEWFOR REFERENCE

查看最近查看的记录

使用“最近查看的项目”资源获取最近查看的记录列表。获取最近查看的两条记录的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/recent/?limit=2 -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{ 
    "attributes" : 
    { 
        "type" : "Account", 
        "url" : "/services/data/v59.0/sobjects/Account/a06U000000CelH0IAJ" 
    }, 
    "Id" : "a06U000000CelH0IAJ", 
    "Name" : "Acme" 
}, 
{ 
    "attributes" : 
    { 
        "type" : "Opportunity", 
        "url" : "/services/data/v59.0/sobjects/Opportunity/a06U000000CelGvIAJ" 
    }, 
    "Id" : "a06U000000CelGvIAJ", 
    "Name" : "Acme - 600 Widgets" 
}

将记录标记为最近查看

若要使用 REST API 将记录标记为最近查看,请使用带有 or 子句的 Query 资源。使用 SOQL 将记录标记为最近查看,以确保 查看记录的日期和时间等信息正确无误 设置。

FOR VIEWFOR REFERENCE

用于在记录出现以下情况时通知 Salesforce: 从自定义界面(如移动应用程序)或自定义页面查看。在引用记录时使用 自定义界面。每次查看相关记录时,都会引用一条记录。为 有关详细信息,请参阅 SOQL 和 SOSL 参考中的“FOR VIEW”和“FOR REFERENCE”。FOR VIEWFOR REFERENCE执行将一个客户记录标记为 最近浏览

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/?q=SELECT+Name+FROM+Account+LIMIT+1+FOR+VIEW -H "Authorization: Bearer token"

用于执行查询的示例请求正文不需要用于执行查询的示例响应正文

{
    "done" : true,
    "totalSize" : 1,
    "records" : 
    [ 
        {  
            "attributes" : 
            {    
                "type" : "Account",    
                "url" : "/services/data/v59.0/sobjects/Account/001D000000IRFmaIAH"  
            },  
            "Name" : "Acme"
        }, 

    ]
}

管理用户密码

本节中的示例使用 REST API 资源来管理用户密码,例如 设置或重置密码。

  • 管理用户密码
    使用 sObject 用户密码资源可以设置、重置或获取有关用户密码的信息。使用 HTTP GET 方法获取密码过期状态,使用 HTTP POST 方法设置密码,使用 HTTP DELETE 方法重置密码。

管理用户密码

使用 sObject 用户密码资源设置、重置或获取有关 用户密码。使用 HTTP GET 方法获取密码过期状态,即 HTTP POST 方法设置密码,并使用 HTTP DELETE 方法重置 密码。

关联的会话必须有权访问给定的用户密码 信息。如果会话没有适当的权限,则 HTTP 错误 403 响应 从这些方法返回。

这些方法适用于用户和自助服务用户。用于管理 自助服务用户密码,而不是在 REST API URL 中使用。SelfServiceUserUser

下面是检索用户当前密码过期状态的示例:获取当前密码过期状态的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/User/005D0000001KyEIIA0/password -H "Authorization: Bearer token"

用于获取当前密码过期状态的示例请求正文不需要用于获取当前密码过期状态的 JSON 示例响应正文

{
    "isExpired" : false
}

用于获取当前密码过期状态的 XML 示例响应正文

<Password>
    <isExpired>false</isExpired>
</Password>

会话权限不足时的错误响应示例

{
    "message" : "You do not have permission to view this record.",
    "errorCode" : "INSUFFICIENT_ACCESS"
}

以下是更改给定用户密码的示例:更改用户密码的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/User/005D0000001KyEIIA0/password -H "Authorization: Bearer token" —H "Content-Type: application/json" —d @newpwd.json —X POST

文件 newpwd.json 的内容

{
    "NewPassword" : "myNewPassword1234"
}

更改用户密码的示例响应成功更改密码时没有响应正文,HTTP 状态代码 204 返回。新密码不符合组织密码时的错误响应示例 要求

{
    "message" : "Your password must have a mix of letters and numbers.",
    "errorCode" : "INVALID_NEW_PASSWORD"
}

最后,下面是重置用户密码的示例:重置用户密码的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/User/005D0000001KyEIIA0/password -H "Authorization: Bearer token" —X DELETE

重置用户密码的示例请求正文不需要用于重置用户密码的 JSON 示例响应正文

{
    "NewPassword" : "2sv0xHAuM"
}

用于重置用户密码的 XML 示例响应正文

<Result>
    <NewPassword>2sv0xHAuM</NewPassword>
</Result>

另见

  • sObject 用户密码

使用审批流程和流程规则

本节中的示例使用 REST API 资源来处理审批流程和 流程规则。

  • 获取所有审批流程的列表 使用“流程
    审批”资源获取有关审批的信息。
  • 提交记录以供审批 使用“流程审批”资源提交记录或记录集合以供审
    批。每个调用都接受一组请求。
  • 审批记录 使用“流程审批”资源可以审批记录或记录
    集合。每个调用都接受一组请求。当前用户必须是分配的审批者。
  • 拒绝记录 使用“流程审批”资源拒绝记录或记录
    集合。每个调用都接受一组请求。当前用户必须是分配的审批者。
  • 批量审批
    使用“流程审批”资源进行批量审批。您可以指定不同流程审批请求的集合,以将它们全部批量执行。
  • 获取流程规则列表 使用“流程规则”资源获取有关流程规则
    的信息。
  • 获取特定流程规则 使用“流程规则
    ”资源,并指定要获取其元数据的规则的 和。sObjectNameworkflowRuleId
  • 触发流程规则 使用“流程规则”资源触发流程规则
    。无论评估标准如何,都将评估与指定 ID 关联的所有规则。所有 ID 必须用于同一对象上的记录。

获取所有审批流程的列表

使用“流程审批”资源获取有关审批的信息。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/approvals/ -H "Authorization: Bearer token"

示例请求正文不需要示例 JSON 响应正文

{
  "approvals" : {
   "Account" : [ {
     "description" : null,
     "id" : "04aD00000008Py9",
     "name" : "Account Approval Process",
     "object" : "Account",
     "sortOrder" : 1
   } ]
  }
}

提交记录以供审批

使用“流程审批”资源提交记录或记录集合以供审批。每次通话 接受一系列请求。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/approvals/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @submit.json"

示例请求正文 submit.json 文件

在以下示例中,提交记录“001D000000I8mIm”以供审批 通过代表提交者跳过其输入标准来处理“PTO_Request_Process” “005D00000015rZy。”

{
"requests" : [{
"actionType": "Submit",
"contextId": "001D000000I8mIm",
"nextApproverIds": ["005D00000015rY9"],
"comments":"this is a test",
"contextActorId": "005D00000015rZy",
"processDefinitionNameOrId" : "PTO_Request_Process",
"skipEntryCriteria": "true"}]
}

示例 JSON 响应正文

[ { 
  "actorIds" : [ "005D00000015rY9IAI" ],
   "entityId" : "001D000000I8mImIAJ",
   "errors" : null,
   "instanceId" : "04gD0000000Cvm5IAC",
   "instanceStatus" : "Pending",
   "newWorkitemIds" : [ "04iD0000000Cw6SIAS" ],
   "success" : true } ]

批准记录

使用“流程审批”资源可以审批记录或记录集合。每次调用都需要一个数组 的请求。当前用户必须是分配的审批者。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/approvals/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @approve.json"

示例请求正文 approve.json 文件

{
  "requests" : [{
    "actionType" : "Approve",
    "contextId" : "04iD0000000Cw6SIAS",
    "nextApproverIds" : ["005D00000015rY9"],
    "comments" : "this record is approved"}]
}

示例 JSON 响应正文

[ { 
  "actorIds" : null,
  "entityId" : "001D000000I8mImIAJ",
  "errors" : null,
  "instanceId" : "04gD0000000CvmAIAS",
  "instanceStatus" : "Approved",
  "newWorkitemIds" : [ ],
  "success" : true 
} ]

拒绝记录

使用“流程审批”资源拒绝记录或记录集合。每次调用都需要一个数组 的请求。当前用户必须是分配的审批者。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/approvals/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @reject.json"

示例请求正文 reject.json 文件

{
  "requests" : [{
    "actionType" : "Reject",
    "contextId" : "04iD0000000Cw6cIAC",
    "comments" : "This record is rejected."}]
}

示例 JSON 响应正文

[ { 
  "actorIds" : null,
  "entityId" : "001D000000I8mImIAJ",
  "errors" : null,
  "instanceId" : "04gD0000000CvmFIAS",
  "instanceStatus" : "Rejected",
  "newWorkitemIds" : [ ],
  "success" : true 
} ]

批量批准

使用“流程审批”资源执行批量审批。您可以指定不同进程的集合 批准请求将它们全部批量执行。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/approvals/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @bulk.json"

示例请求正文 bulk.json 文件

{
  "requests" :
  [{
    "actionType" : "Approve",
    "contextId" : "04iD0000000Cw6r",
    "comments" : "approving an account"
    },{
    "actionType" : "Submit",
    "contextId" : "001D000000JRWBd",
    "nextApproverIds" : ["005D00000015rY9"],
    "comments" : "submitting an account"
    },{
    "actionType" : "Submit",
    "contextId" : "003D000000QBZ08",
    "comments" : "submitting a contact"
    }]
}

示例 JSON 响应正文

[ { 
  "actorIds" : null,
  "entityId" : "001D000000I8mImIAJ",
  "errors" : null,
  "instanceId" : "04gD0000000CvmZIAS",
  "instanceStatus" : "Approved",
  "newWorkitemIds" : [ ],
  "success" : true 
  }, {
  "actorIds" : null,
  "entityId" : "003D000000QBZ08IAH",
  "errors" : null,
  "instanceId" : "04gD0000000CvmeIAC",
  "instanceStatus" : "Approved",
  "newWorkitemIds" : [ ],
  "success" : true
  }, {
  "actorIds" : [ "005D00000015rY9IAI" ],
  "entityId" : "001D000000JRWBdIAP",
  "errors" : null,
  "instanceId" : "04gD0000000CvmfIAC",
  "instanceStatus" : "Pending",
  "newWorkitemIds" : [ "04iD0000000Cw6wIAC" ],
  "success" : true
} ]

获取流程规则列表

使用“流程规则”资源获取有关流程规则的信息。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/rules/ -H "Authorization: Bearer token"

示例请求正文不需要示例 JSON 响应正文

{
  "rules" : {
    "Account" : [ {
      "actions" : [ {
        "id" : "01VD0000000D2w7",
        "name" : "ApprovalProcessTask",
        "type" : "Task"
      } ],
      "description" : null,
      "id" : "01QD0000000APli",
      "name" : "My Rule",
      "namespacePrefix" : null,
      "object" : "Account"
    } ]
  }
}

获取特定进程规则

使用“流程规则”资源并指定 和 要获取其元数据的规则。sObjectNameworkflowRuleId示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/rules/Account/01QD0000000APli -H "Authorization: Bearer token"

示例请求正文不需要示例 JSON 响应正文

{
  "actions" : [ {
    "id" : "01VD0000000D2w7",
    "name" : "ApprovalProcessTask",
    "type" : "Task"
    } ],
    "description" : null,
    "id" : "01QD0000000APli",
    "name" : "My Rule",
    "namespacePrefix" : null,
    "object" : "Account"
}

触发流程规则

使用“流程规则”资源触发流程规则。与指定 ID 关联的所有规则都将 无论评估标准如何,都要进行评估。所有 ID 必须用于同一记录 对象。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/process/rules/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @rules.json"

示例请求正文 rules.json 文件

{
  "contextIds" : [
    "001D000000JRWBd",
    "001D000000I8mIm",
    "001D000000I8aaf"]
}

示例 JSON 响应正文

{
  "errors" : null,
  "success" : true
}

使用事件监视

这些示例使用 REST API 事件监视数据,其中包含对 评估组织的使用趋势和用户行为。通过闪电网络访问事件监控 平台 SOAP API 和 REST API,通过 EventLogFile 对象。因此,您可以集成 使用您自己的后端存储和数据集市记录数据,以关联来自多个组织的数据,以及 跨不同的系统。

注意

有关可用于事件监控的受支持事件类型,请参阅 Salesforce 和 Lightning 的对象参考 平台:EventLogFile 对象。

  • 在极少数情况下,如果 24 小时内未生成日志文件, 请联系 Salesforce 客户支持。
  • 日志数据是只读的。您无法插入、更新或删除日志数据。
  • 要确定为您的组织生成了哪些文件,请使用 EventType 字段。
  • 事件实时生成日志数据。但是,每日日志文件会在 事件发生后第二天的非高峰时段。因此,每日日志文件数据为 活动结束后至少 1 天内不可用。对于每小时日志文件,具体取决于事件 交付和最终处理时间,预计事件将在 3-6 小时内发生 日志文件中可用的事件。但是,这可能需要更长的时间。
  • 仅当某一类型的事件(由 EventType 字段表示)在一天或一小时内发生时,才会生成日志文件。如果没有发生任何事件, 不会生成文件。
  • 日志文件在组织中的 CreatedDate后 30 天内可用 具有事件监控许可证,之后将自动删除。在所有开发人员中 版本组织、日志文件的有效期为 1 天。
  • 所有事件监控日志都通过 EventLogFile 对象向 API 公开。但是,除了通过事件之外,无法通过用户界面进行访问 监视 Analytics 应用。
  • 日志文件不计入组织的数据或文件存储分配。
  • 事件监视日志文件不是用户活动的记录系统。他们是一个来源 真相,但它们并不持久。在 Salesforce 站点切换、实例刷新或 可能会发生计划外的系统中断、数据丢失。例如,如果 Salesforce 将 生产组织实例,则事件日志文件中可能存在数据缺口。Salesforce 使 为保持事件日志文件数据完整性和避免数据而做出的商业合理努力 损失。当 Salesforce 执行站点切换或实例刷新时,它使用自动 复制事件日志的进程。
  • 提供每小时一次的事件日志文件,供您在 加速基础。但是,您可能无法每小时获取所有事件日志数据 事件日志文件,尤其是在站点切换、实例刷新或计划外系统期间 中断。要获得完整数据,请使用每日日志文件。
  • 如果事件传输失败需要很长时间才能从中恢复,则会重新传输日志文件 以确保它们至少交付一次。因此,潜在日志文件可以 有时包含重复的事件数据。当应用程序使用潜在日志文件时, 确保您的应用程序处理重复的事件传递。
  • 交付每日增量日志文件时,新文件会将原始文件替换为 该日期的完整可用日志集。为了确保您看到的最多 最近的日志文件,请选中 CreatedDate 字段。
  • 我们建议您始终查询 EventLogFile 对象以获取新的日志文件,以确保 你也包括潜在的。若要标识新创建的日志文件,请使用 EventLogFile CreatedDate 字段。每小时和每天的增量日志下发 不同。有关详细信息,请参阅每小时和 24 小时事件日志之间的差异。

本部分中的所有查询和示例都需要启用 View 事件日志文件和 API 用户权限。具有“查看所有数据”权限的用户还可以查看事件监控 数据。

  • 使用 REST
    描述事件监视 使用 sObject Describe 资源检索对象的所有元数据,包括有关字段、URL 和子关系的信息。
  • 使用 REST
    查询事件监视数据 使用 Query 资源从记录中检索字段值。在 fields 参数中指定要检索的字段,并使用资源的方法。GET
  • 从记录
    中获取事件监视内容 使用 sObject Blob Retrieve 资源检索给定记录的 BLOB 数据。
  • 将 cURL 与 REST
    结合使用下载大型事件日志文件 您可能有一些事件日志文件大于工具可以处理的范围。命令行工具(如 cURL)是使用 sObject Blob Get 对象下载大于 100 MB 的文件的一种方法
  • 删除事件监视数据 可以删除包含用户日志数据
    的事件日志文件。删除日志文件有助于您遵守数据保护和隐私法规,并控制其他人可以访问的信息。不能从事件日志中删除单个行。相反,您必须删除包含用户活动的整个日志文件。
  • 查询或查看每小时事件日志文件
    若要加速查看组织中的事件,请以每小时为增量获取最近活动的事件日志文件。每小时一次的事件日志文件可以让你更快地了解安全异常和自定义代码性能问题。

描述使用 REST 进行事件监视

使用 sObject Describe 资源检索对象的所有元数据,包括有关字段的信息。 URL 和子关系。例可以使用 REST API 来描述事件日志文件。使用 GET 请求,例如 这:

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/EventLogFile/describe -H "Authorization: Bearer token"

原始响应示例

{ 
   "actionOverrides" : [ ],
   "activateable" : false,
   "childRelationships" : [ ],
   "compactLayoutable" : false,
   "createable" : false,
   "custom" : false,
   "customSetting" : false,
   "deletable" : false,
   "deprecatedAndHidden" : false,
   "feedEnabled" : false,
   "fields" : [ {
     "autoNumber" : false,
     "byteLength" : 18,
     "calculated" : false,
     "calculatedFormula" : null,
     "cascadeDelete" : false,
     "caseSensitive" : false,
     "controllerName" : null,
     "createable" : false,
     ...
}

使用 REST 查询事件监控数据

使用查询资源 从记录中检索字段值。指定要在 fields 参数并使用 资源。

GET您可以使用 REST API 查询事件监控数据。检索事件监视记录 根据 LogDate 和 EventType,使用 GET 像这样请求:

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query?q=SELECT+Id+,+EventType+,+LogFile+
,+LogDate+,+LogFileLength+FROM+EventLogFile+WHERE+
LogDate+>+Yesterday+AND+EventType+=+'API' -H "Authorization: Bearer token"

原始响应示例

{ 
   "totalSize" : 4,
   "done" : true,
   "records" : [ {
     "attributes" : {
       "type" : "EventLogFile",
       "url" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000001bROAQ"     }
     "Id" : "0ATD000000001bROAQ",
     "EventType" : "API",
     "LogFile" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000001bROAQ/LogFile",
     "LogDate" : "2014-03-14T00:00:00.000+0000",
     "LogFileLength" : 2692.0
    }, {
     "attributes" : {
       "type" : "EventLogFile",
       "url" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000001SdOAI"     },
       "Id" : "0ATD000000001SdOAI",
       "EventType" : "API",
       "LogFile" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000001SdOAI/LogFile",
       "LogDate" : "2014-03-13T00:00:00.000+0000",
       "LogFileLength" : 1345.0
   }, {
       "attributes" : {
        "type" : "EventLogFile",
        "url" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000003p1OAA"     },
        "Id" : "0ATD000000003p1OAA",
        "EventType" : "API",
        "LogFile" : "/services/data/v59.0/sobjects/EventLogFile/0ATD000000003p1OAA/LogFile",
        "LogDate" : "2014-06-21T00:00:00.000+0000",
        "LogFileLength" : 605.0   },
 {     "attributes" : {
       "type" : "EventLogFile",
       "url" : "/services/data/v59.0/sobjects/EventLogFile/0ATD0000000055eOAA"     },
       "Id" : "0ATD0000000055eOAA",
       "EventType" : "API",
       "LogFile" : "/services/data/v59.0/sobjects/EventLogFile/0ATD0000000055eOAA/LogFile",
       "LogDate" : "2014-07-03T00:00:00.000+0000",
       "LogFileLength" : 605.0
     } ]
}

从记录中获取事件监视内容

使用 sObject Blob 检索资源以检索给定记录的 BLOB 数据。例可以使用 REST API 检索 BLOB 数据以进行事件监视。使用 GET 与此类似的请求:

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/EventLogFile/0ATD000000000pyOAA/LogFile -H "Authorization: Bearer token"

示例响应正文事件监视内容以二进制形式返回。请注意,响应 内容类型不会是 JSON 或 XML,因为返回的数据是 二元的。

HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 16:46:10 GMT
Sforce-Limit-Info: api-usage=135/5000
Content-Type: application/octetstream
Transfer-Encoding: chunked
"EVENT_TYPE", "ORGANIZATION_ID", "TIMESTAMP","USER_ID", "CLIENT_IP",
"URI", "REFERRER_URI", "RUN_TIME"
"URI", "00DD0000000K5xD", "20130728185606.020", "005D0000001REDy",
"10.0.62.141", "/secur/contentDoor", "https-//login-salesforce-com/",
"11"
"URI", "00DD0000000K5xD", "20130728185556.930", "005D0000001REI0",
"10.0.62.141", "/secur/logout.jsp", "https-//MyDomainName-my-salesforce-com/00O/o",
"54"
"URI", "00DD0000000K5xD", "20130728185536.725", "005D0000001REI0",
"10.0.62.141", "/00OD0000001ckx3",
"https-//MyDomainName-my-salesforce-com/00OD0000001ckx3", "93"

使用带有 REST 的 cURL 下载大型事件日志文件

您可能有一些事件日志文件大于工具可以处理的范围。一个 命令行工具(如 cURL)是下载大于 100 MB 的文件的一种方法,使用 sObject Blob Get 对象示例:使用“X-PrettyPrint”标头和“-o”标志输出大文件 转换为.csv格式此命令将文件下载到计算机上的下载文件夹中。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/EventLogFile/0AT30000000000uGAA/LogFile
-H "Authorization: Bearer token" -H "X-PrettyPrint:1" -o ~/downloads/outputLogFile.csv

建议在下载大型事件日志文件时使用压缩。请参阅压缩标头。

删除事件监控数据

您可以删除包含用户日志数据的事件日志文件。删除日志文件 帮助您遵守数据保护和隐私法规并控制信息 其他人可以访问。不能从事件日志中删除单个行。相反,您必须 删除包含用户活动的整个日志文件。若要删除事件日志文件,请在安装程序中启用删除,并创建一个权限集 包括“删除事件监控记录”用户权限,并分配此权限 权限集。(或者,您可以将用户权限分配给 自定义配置文件。然后,这些用户可以通过以下方式查询和删除 EventLogFile 记录 在REST或SOAP中使用查询和删除资源。

delete()

注意

您无法从事件中删除单个行 原木。由于事件日志以 blob 格式存储在数据库中,因此必须 删除包含用户活动的整个日志文件。

  1. 在“设置”的“快速查找”框中,输入“事件”,然后 选择事件监控设置
  2. 启用删除事件监视数据。此操作记录在安装程序中 审计跟踪。“删除事件监控记录”用户权限现在可用于 分配给权限集。(或者,您可以分配用户权限 添加到自定义配置文件。
  3. 在“设置”的“快速查找”框中,输入“权限”,然后 ,然后选择“权限集”。
  4. 创建包含“删除事件监视记录”用户的权限集 权限,然后保存权限集。
  5. 在“设置”的“快速查找”框中,输入用户,然后 选择“用户”。
  6. 选择要授予删除事件监控权限的用户 数据。
  7. 在此用户的“权限集分配”部分中,分配权限 设置,然后单击保存。此操作记录在安装程序中 审计跟踪。分配了此权限集(或任何自定义配置文件,包括 删除事件监控记录用户权限)现在可以删除事件 监控数据。后续步骤将介绍如何使用 API 删除 数据。
  8. 若要查找包含要删除的用户活动的日志,请查询 EventLogFile 对象。有关详细信息,请参阅查询事件监控数据 休息。
  9. 记下返回日志的 ID。
  10. 使用 sObject Rows 资源删除记录。指定记录 ID,并使用 DELETE 方法。有关详细信息,请参阅删除 记录。

查询或查看每小时事件日志文件

若要加速查看组织中的事件,请每小时获取一次事件日志文件 最近活动的增量。每小时事件日志文件可让您更快地了解 安全异常和自定义代码性能问题。

用户权限 需要
要访问 API 和查询日志文件,请执行以下操作:启用 API 并查看事件日志文件
要查看事件日志文件,请执行以下操作:查看所有数据

例子

假设你是一名安全分析师,负责监视异常用户行为。通过拉动更多 频繁更新您的安全系统,您可以收到可疑事件的警报 在几个小时内发生,而不是一两天后。

在另一个示例中,假设您是一名开发人员。您已经确定了一系列 Apex 组织中的失败,并且您希望主动重构 Apex 代码以改进 性能。您可以查看每小时的日志文件,以查明问题并修复您的代码 数小时后,您的最终用户才开始抱怨性能不佳。

考虑

  • 每小时事件日志文件与事件监控分析应用程序的集成是 不能利用的。
  • 根据事件传递和最终处理时间,事件应 从事件发生开始需要三到六个小时才能在日志中显示 文件。但是,这可能需要更长的时间。
  • 当处理出现延迟且特定小时的事件日志到达时 稍后,将为事件/日期/小时创建一个新的日志文件,并仅列出 新事件。使用创建日期和增量序列号 标识新的日志文件。始终使用最近处理的事件日志 特定日期的文件。但是,如果事件日志文件已经 拉入第三方应用程序时,它们可能需要在 该应用程序。如果同时启用了每小时日志和每日日志,则每日日志始终具有序列 数字为 0,因为每个每日间隔只有一个文件。创建日期 指示文件的生成时间。如果 CreatedDate 在最后一个之后 事件日志文件下载时,有新事件需要处理。有关最佳做法,请在 WHERE 子句中使用 CreatedDate 来选择日志 在上次下载的事件日志文件之后创建。例如,如果最后一个 下载的文件是在 2018 年 2 月 1 日中午 12 点,要查找下一个日志文件,请使用 +CreatedDate+>+“2018-02-01T12:00:00Z”。
  • 在站点切换、实例刷新或 计划外系统中断。但是,在站点切换和实例刷新期间, Salesforce 通过以下方式做出商业上合理的努力来避免此类数据丢失 使用自动化过程复制事件日志。
  • 如果 24 小时内未生成日志文件,请联系 Salesforce 支持。
  • 查询每小时事件日志文件 查询每小时事件日志文件的方式与查询 24 小时日志文件
    的方式相同。
  • 每小时事件日志和 24 小时事件日志
    之间的差异 除了 24 小时日志文件外,您大约每小时都会收到一次事件日志文件。查看两个日志之间的差异,以便可以筛选文件以分析所需的事件数据。

查询每小时事件日志文件

查询每小时事件日志文件的方式与查询 24 小时日志的方式相同 文件。

假设您是管理员。您的首席安全官要求您确定谁 修改了过去两个小时内的特定客户和商机。您查询每小时 使用 EventLogFile 对象查看页面请求的 URI 事件日志文件,以及 请求状态。由于 EventLogFile 还返回 24 小时日志文件,因此请使用此 SOQL 语法来筛选出 24 小时日志文件。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query?​q=SELECT+Id+,​+EventType+,​+Interval+,+LogDate+,​+LogFile+​FROM+EventLogFile+​WHERE+EventType+=+'URI'+​AND+Interval+=+'Hourly' -H "Authorization: Bearer token"

在查询中,确保仅 每小时返回一次事件日志文件数据。或者,可以使用 Sequence 筛选出 24 小时事件日志文件 ()。若要同时获取每小时和 24 小时文件,请使用 .Interval=HourlySequence!=0Sequence>=0

如果您的沙盒组织具有 URI 事件,您会在查询结果中看到日志文件记录。您可以 此外,下载事件日志文件以查看 CSV 文件中的数据。查看更多 信息,请参阅 Trailhead:下载和 可视化事件日志文件

每小时和 24 小时事件日志之间的差异

除了 24 小时日志文件外,您大约每小时都会收到一次事件日志文件。 查看两个日志之间的差异,以便可以筛选文件以分析事件 您想要的数据。

每小时日志文件24小时日志文件
为每小时的活动生成一个或多个文件。每 24 小时活动生成一个文件。
在 API 中可用。您可以手动将数据导入第三方可视化 应用程序。在 API 中可用,并与 Event Monitoring Analytics 应用程序集成,以及 第三方可视化应用程序。
EventLogFile 对象中的关键值为:间隔 – 每小时CreatedDate – 创建日志文件的时间戳。 使用此字段标识新文件。LogDate – 时间戳,用于标记以下时间间隔的开始时间 事件发生了。例如,对于上午 11:00 到中午 12:00 之间发生的事件 在 2016 年 3 月 7 日,此字段的值为 2016-03-07T11:00:00.000Z。序列 (Sequence) – 1+。当事件添加到 创建最新事件日志文件后的同一小时。该值在 随后的一小时。另请参阅有关每小时事件日志的这些注意事项。EventLogFile 对象中的关键值为:间隔 – 每天CreatedDate – 创建日志文件的时间戳。 使用此字段标识新文件。LogDate – 时间戳,用于标记以下时间间隔的开始时间 事件发生了。例如,对于 2016 年 3 月 7 日发生的事件,此字段的 值为 2016-03-07T00:00:00.000+0000。序列 (Sequence) – 0
当传送每小时增量日志文件时,包含该小时新日志的文件 已创建。对于每个新文件,“序列”字段都会递增。当交付每日增量日志文件时,一个新文件将替换原始文件 以及该日期的完整可用日志集。“CreatedDate”字段已更新。

注意

与 24 小时事件监控一样,过去 30 年的每小时事件日志数据可用 日。

使用复合资源

本节中的示例使用复合资源来改进应用程序的 通过最小化客户端和服务器之间的往返次数来提高性能。

  • 在单个 API 调用中执行依赖请求 以下示例使用 Composite 资源在单个调用
    中执行多个依赖请求。首先,它创建一个帐户并检索其信息。接下来,它使用客户数据和复合资源的引用 ID 功能来创建联系人,并根据客户数据填充其字段。然后,它使用请求字符串中的查询参数检索有关帐户所有者的特定信息。最后,如果元数据自特定日期以来已被修改,则检索帐户元数据。composite.json 文件包含复合请求和子请求数据。
  • 更新客户,创建联系人,并将其与联结对象
    链接 下面的示例使用 Composite 资源更新客户的某些字段,创建联系人,并将这两条记录与名为 .所有这些请求都在一次调用中执行。composite.json 文件包含复合请求和子请求数据。AccountContactJunction
  • 在单个请求中更新记录并获取其字段值 使用复合批处理资源在单个 API 调用中执行多个请求。
  • 更新插入帐户并创建联系人
    以下示例使用 Composite 资源更新插入客户并创建链接到该客户的联系人。所有这些请求都在一次调用中执行。composite.json 文件包含复合请求和子请求数据。
  • 创建嵌套记录
    使用 sObject Tree 资源创建共享根记录类型的嵌套记录。例如,在单个请求中,您可以创建一个帐户及其子联系人,并创建一个第二个帐户及其子帐户和联系人。处理请求后,将创建记录,并通过 ID 自动链接父子。在请求数据中,提供记录层次结构、必填字段值和可选字段值、每条记录的类型以及每条记录的引用 ID,然后使用资源的 POST 方法。如果请求成功,响应正文将包含所创建记录的 ID。否则,响应仅包含导致错误的记录的引用 ID 和错误信息。
  • 创建多条记录 虽然资源可用于创建嵌套记录,但您也可以创建多个相同类型的不相关记录
    。在单个请求中,您最多可以创建 200 条记录。在请求数据中,为每条记录提供必填字段值和可选字段值、每条记录的类型以及每条记录的引用 ID,然后使用资源的 POST 方法。如果请求成功,响应正文将包含所创建记录的 ID。否则,响应仅包含导致错误的记录的引用 ID 和错误信息。
  • 使用复合图 复合图
    提供了一种执行复合请求的增强方法,复合请求在单个调用中执行一系列 REST API 请求。
  • 使用复合图 此示例演示如何使用复合图
    。它还演示了一个请求如何使用多个复合图。
  • 复合请求和集合请求
    中的 allOrNone 参数 如果复合请求使用 sObject 集合,则有两个或多个参数可以交互,一个在复合请求上,一个在各个 sObject 集合子请求上。allOrNone

在单个 API 调用中执行依赖请求

以下示例使用 Composite 资源执行多个依赖 在一次调用中完成所有请求。首先,它创建一个帐户并检索其信息。 接下来,它使用帐户数据和复合资源的引用 ID 功能来 创建联系人并根据客户数据填充其字段。然后它检索 在请求中使用查询参数提供有关帐户所有者的特定信息 字符串。最后,如果元数据自特定日期以来被修改,它将检索 帐户元数据。composite.json 文件包含复合 请求和子请求数据。在单个 API 调用中执行依赖请求

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@composite.json"

请求正文 composite.json 文件

{
    "allOrNone" : true,
    "compositeRequest" : [{
        "method" : "POST",
        "url" : "/services/data/v59.0/sobjects/Account",
        "referenceId" : "NewAccount",
        "body" : {  
            "Name" : "Salesforce",
            "BillingStreet" : "Landmark @ 1 Market Street",
            "BillingCity" : "San Francisco",
            "BillingState" : "California",
             "Industry" : "Technology"
        }
    },{
        "method" : "GET",
        "referenceId" : "NewAccountInfo",
        "url" : "/services/data/v59.0/sobjects/Account/@{NewAccount.id}"
    },{
        "method" : "POST",
        "referenceId" : "NewContact",
        "url" : "/services/data/v59.0/sobjects/Contact",
        "body" : {  
            "lastname" : "John Doe",
            "Title" : "CTO of @{NewAccountInfo.Name}",
            "MailingStreet" : "@{NewAccountInfo.BillingStreet}",
            "MailingCity" : "@{NewAccountInfo.BillingAddress.city}",
            "MailingState" : "@{NewAccountInfo.BillingState}",
            "AccountId" : "@{NewAccountInfo.Id}",
            "Email" : "jdoe@salesforce.com",
            "Phone" : "1234567890"
        }
    },{
        "method" : "GET",
        "referenceId" : "NewAccountOwner",
        "url" : "/services/data/v59.0/sobjects/User/@{NewAccountInfo.OwnerId}?fields=Name,companyName,Title,City,State"
    },{
        "method" : "GET",
        "referenceId" : "AccountMetadata",
        "url" : "/services/data/v59.0/sobjects/Account/describe",
        "httpHeaders" : {
            "If-Modified-Since" : "Tue, 31 May 2016 18:13:37 GMT"
        }
    }]
}

成功执行复合请求后的响应正文

{
    "compositeResponse" : [{
        "body" : {
            "id" : "001R00000033JNuIAM",
            "success" : true,
            "errors" : [ ]
        },
        "httpHeaders" : {
          "Location" : "/services/data/v59.0/sobjects/Account/001R00000033JNuIAM"
        },
        "httpStatusCode" : 201,
        "referenceId" : "NewAccount"
    },{
        "body" : {
            all the account data
        },
        "httpHeaders" : {
            "ETag" : "\"Jbjuzw7dbhaEG3fd90kJbx6A0ow=\"",
            "Last-Modified" : "Fri, 22 Jul 2016 20:19:37 GMT"
        },
        "httpStatusCode" : 200,
        "referenceId" : "NewAccountInfo"
    },{
        "body" : {
            "id" : "003R00000025REHIA2",
            "success" : true,
            "errors" : [ ]
        },
        "httpHeaders" : {
            "Location" : "/services/data/v59.0/sobjects/Contact/003R00000025REHIA2"
        },
        "httpStatusCode" : 201,
        "referenceId" : "NewContact"
    },{
        "body" : {
            "attributes" : {
            "type" : "User",
            "url" : "/services/data/v59.0/sobjects/User/005R0000000I90CIAS"
            },
            "Name" : "Jane Doe",
            "CompanyName" : "Salesforce",
            "Title" : Director,
            "City" : "San Francisco",
            "State" : "CA",
            "Id" : "005R0000000I90CIAS"
        },
        "httpHeaders" : { },
        "httpStatusCode" : 200,
        "referenceId" : "NewAccountOwner"
    },{
        "body" : null,
        "httpHeaders" : {
            "ETag" : "\"f2293620\"",
            "Last-Modified" : "Fri, 22 Jul 2016 18:45:56 GMT"
         },
        "httpStatusCode" : 304,
        "referenceId" : "AccountMetadata"
    }]
}

更新帐户,创建联系人,并将其与联结链接 对象

以下示例使用 Composite 资源更新 帐户,创建联系人,并将这两条记录与名为 的联结对象链接。所有这些请求都在 一个电话。composite.json 文件包含复合请求 和子请求数据。

AccountContactJunction更新帐户,创建联系人,并将其与联结对象链接

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@composite.json"

请求正文 composite.json 文件

{
    "allOrNone" : true,
    "compositeRequest" : [{
        "method" : "PATCH",
        "url" : "/services/data/v59.0/sobjects/Account/001xx000003DIpcAAG",
        "referenceId" : "UpdatedAccount",
        "body" : {  
            "Name" : "Salesforce",
            "BillingStreet" : "Landmark @ 1 Market Street",
            "BillingCity" : "San Francisco",
            "BillingState" : "California",
            "Industry" : "Technology"
        }
    },{
        "method" : "POST",
        "referenceId" : "NewContact",
        "url" : "/services/data/v59.0/sobjects/Contact/",
        "body" : {  
            "lastname" : "John Doe",
            "Phone" : "1234567890"
        }
    },{
        "method" : "POST",
        "referenceId" : "JunctionRecord",
        "url" : "/services/data/v59.0/sobjects/AccountContactJunction__c",
        "body" : {  
            "accountId__c" : "001xx000003DIpcAAG",
            "contactId__c" : "@{NewContact.id}"
        }
    }]
}

成功执行复合请求后的响应正文

{
  "compositeResponse" : [{
    "body" : null,
    "httpHeaders" : { },
    "httpStatusCode" : 204,
    "referenceId" : "UpdatedAccount"
  }, {
    "body" : {
      "id" : "003R00000025R22IAE",
      "success" : true,
      "errors" : [ ]
    },
    "httpHeaders" : {
      "Location" : "/services/data/v59.0/sobjects/Contact/003R00000025R22IAE"
    },
    "httpStatusCode" : 201,
    "referenceId" : "NewContact"
  }, {
    "body" : {
      "id" : "a00R0000000iN4gIAE",
      "success" : true,
      "errors" : [ ]
    },
    "httpHeaders" : {
      "Location" : "/services/data/v59.0/sobjects/AccountContactJunction__c/a00R0000000iN4gIAE"
    },
    "httpStatusCode" : 201,
    "referenceId" : "JunctionRecord"
  }]
}

更新记录并在单个中获取其字段值 请求

使用复合批处理资源在单个 API 中执行多个请求 叫。

以下示例更新帐户的名称并获取该帐户的一些字段 单个请求中的值。batch.json 文件包含 子请求数据。更新记录并在单个中查询其名称和帐单邮政编码 请求

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/batch/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@batch.json"

请求正文 batch.json 文件

{
"batchRequests" : [
    {
    "method" : "PATCH",
    "url" : "v59.0/sobjects/account/001D000000K0fXOIAZ",
    "richInput" : {"Name" : "NewName"}
    },{
    "method" : "GET",
    "url" : "v59.0/sobjects/account/001D000000K0fXOIAZ?fields=Name,BillingPostalCode"
    }]
}

成功执行子请求后的响应正文

{
   "hasErrors" : false,
   "results" : [{
      "statusCode" : 204,
      "result" : null
      },{
      "statusCode" : 200,
      "result": {
         "attributes" : {
            "type" : "Account",
            "url" : "/services/data/v59.0/sobjects/Account/001D000000K0fXOIAZ"
         },
         "Name" : "NewName",
         "BillingPostalCode" : "94105",
         "Id" : "001D000000K0fXOIAZ"
      }
   }]
}

另见

  • 复合批次

更新插入帐户并创建联系人

以下示例使用 Composite 资源更新插入帐户并创建一个 链接到该帐户的联系人。所有这些请求都在一次调用中执行。composite.json 文件包含复合请求和子请求 数据。更新插入帐户并创建联系人

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@composite.json"

请求正文 composite.json 文件

{
    "allOrNone" : true,
    "compositeRequest": [{
        "method": "PATCH",
        "url": "/services/data/v59.0/sobjects/Account/ExternalAcctId__c/ID12345",
        "referenceId": "NewAccount",
        "body": {
            "Name": "Acme"
        }
    },{
        "method" : "POST",
        "url" : "/services/data/v59.0/sobjects/Contact",
        "referenceId" : "newContact",
        "body" : {
            "LastName" : "Harrison",
            "AccountId" : "@{NewAccount.id}"
        }
    }]
}

成功执行复合请求后的响应正文

{
    "compositeResponse" : [{
        "body" : {
            "id" : "0016g00000Wqu1EAAR",
            "success" : true,
            "errors" : [ ],
            "created" : true
        },
        "httpHeaders" : {
            "Location" : "/services/data/v59.0/sobjects/Account/0016g00000Wqu1EAAR"
        },
        "httpStatusCode" : 201,
        "referenceId" : "NewAccount"
    },{
        "body" : {
            "id" : "0036g00000WKnfLAAT",
            "success" : true,
            "errors" : [ ]
        },
        "httpHeaders" : {
            "Location" : "/services/data/v59.0/sobjects/Contact/0036g00000WKnfLAAT"
        },
        "httpStatusCode" : 201,
        "referenceId" : "newContact"
    }]
}

另见

  • 按外部 ID 划分的 sObject 行

创建嵌套记录

使用 sObject 树资源创建共享根记录类型的嵌套记录。 例如,在单个请求中,您可以创建一个帐户及其子联系人, 第二个帐户及其子帐户和联系人。一旦请求 处理后,将创建记录,并通过 ID 自动链接父子。 在请求数据中,您提供记录层次结构、必填字段和可选字段值, 每条记录的类型,以及每条记录的引用 ID,然后使用 资源。如果请求是 成功的。否则,响应仅包含导致 错误和错误信息。

下面的示例创建两组嵌套记录。第一组包括一个 帐户和两个子项联系记录。第二组包括一个帐户,一个子 客户记录和 1 个子联系人记录。记录数据在 newrecords.json 中提供。创建两个新帐户及其子记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/tree/Account/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@newrecords.json"

用于创建两个请求正文 newrecords.json 文件的示例 新帐户及其子记录

{
"records" :[{
    "attributes" : {"type" : "Account", "referenceId" : "ref1"},
    "name" : "SampleAccount1",
    "phone" : "1234567890",
    "website" : "www.salesforce.com",
    "numberOfEmployees" : "100",
    "industry" : "Banking",
    "Contacts" : {
      "records" : [{
         "attributes" : {"type" : "Contact", "referenceId" : "ref2"},
         "lastname" : "Smith",
         "Title" : "President",
         "email" : "sample@salesforce.com"
         },{
         "attributes" : {"type" : "Contact", "referenceId" : "ref3"},
         "lastname" : "Evans",
         "title" : "Vice President",
         "email" : "sample@salesforce.com"
         }]
      }
    },{
    "attributes" : {"type" : "Account", "referenceId" : "ref4"},
    "name" : "SampleAccount2",
    "phone" : "1234567890",
    "website" : "www.salesforce.com",
    "numberOfEmployees" : "52000",
    "industry" : "Banking",
    "childAccounts" : {
      "records" : [{
        "attributes" : {"type" : "Account", "referenceId" : "ref5"},
        "name" : "SampleChildAccount1",
        "phone" : "1234567890",
        "website" : "www.salesforce.com",
        "numberOfEmployees" : "100",
        "industry" : "Banking"
        }]
      },
    "Contacts" : {
      "records" : [{
        "attributes" : {"type" : "Contact", "referenceId" : "ref6"},
        "lastname" : "Jones",
        "title" : "President",
        "email" : "sample@salesforce.com"
        }]
      }
  }]
}

成功创建记录和关系后的示例响应正文

{
    "hasErrors" : false,
    "results" : [{
     "referenceId" : "ref1",
     "id" : "001D000000K0fXOIAZ"
     },{
     "referenceId" : "ref4",
     "id" : "001D000000K0fXPIAZ"
     },{
     "referenceId" : "ref2",
     "id" : "003D000000QV9n2IAD"
     },{
     "referenceId" : "ref3",
     "id" : "003D000000QV9n3IAD"
     },{
     "referenceId" : "ref5",
     "id" : "001D000000K0fXQIAZ"
     },{
     "referenceId" : "ref6",
     "id" : "003D000000QV9n4IAD"
     }]
}

处理请求后,将使用父子项创建所有六条记录 请求中指定的关系。

另见

  • sObject 树

创建多条记录

虽然该资源可用于创建嵌套记录,但您可以 此外,创建多个相同类型的不相关记录。在单个请求中,您可以 创建多达 200 条记录。在请求数据中,提供必需和可选 每条记录的字段值、每条记录的类型以及每条记录的引用 ID,以及 然后使用资源的 POST 方法。响应正文将包含 如果请求成功,则创建记录。否则,响应仅包含 导致错误的记录的引用 ID 和错误信息。

以下示例创建四个新帐户。记录数据在 newrecords.json 中提供。创建四个新帐户的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/tree/Account/ -H "Authorization: Bearer token -H "Content-Type: application/json" -d "@newrecords.json"

用于创建四个的请求正文 newrecords.json 文件示例 新账户

{
"records" :[{
    "attributes" : {"type" : "Account", "referenceId" : "ref1"},
    "name" : "SampleAccount1",
    "phone" : "1111111111",
    "website" : "www.salesforce.com",
    "numberOfEmployees" : "100",
    "industry" : "Banking"   
    },{
    "attributes" : {"type" : "Account", "referenceId" : "ref2"},
    "name" : "SampleAccount2",
    "phone" : "2222222222",
    "website" : "www.salesforce2.com",
    "numberOfEmployees" : "250",
    "industry" : "Banking"
    },{
    "attributes" : {"type" : "Account", "referenceId" : "ref3"},
    "name" : "SampleAccount3",
    "phone" : "3333333333",
    "website" : "www.salesforce3.com",
    "numberOfEmployees" : "52000",
    "industry" : "Banking"
    },{
    "attributes" : {"type" : "Account", "referenceId" : "ref4"},
    "name" : "SampleAccount4",
    "phone" : "4444444444",
    "website" : "www.salesforce4.com",
    "numberOfEmployees" : "2500",
    "industry" : "Banking"
    }]
}

成功创建记录后的示例响应正文

{
    "hasErrors" : false,
    "results" : [{
     "referenceId" : "ref1",
     "id" : "001D000000K1YFjIAN"
     },{
     "referenceId" : "ref2",
     "id" : "001D000000K1YFkIAN"
     },{
     "referenceId" : "ref3",
     "id" : "001D000000K1YFlIAN"
     },{
     "referenceId" : "ref4",
     "id" : "001D000000K1YFmIAN"     
     }]
}

另见

  • sObject 树

使用复合图

复合图提供了一种增强的方法来执行复合请求,这些请求执行 单个调用中的一系列 REST API 请求。

  • 常规复合请求允许您执行一系列 REST API 单个调用中的请求。您可以将一个请求的输出用作 输入到后续请求中。
  • 复合图扩展了常规的复合请求,允许您将 复杂而完整的一系列相关对象和记录。
  • 复合图还使您能够确保一组给定请求中的步骤是 要么全部完成,要么全部未完成。如果使用此选项,则不会 必须检查哪些请求成功。
  • 常规复合请求的子请求限制为 25 个。复合图增加了这一点 限制为 500。

定义复合图

通常,图形是连接节点的集合。

在复合的背景下 图操作,节点是复合子请求。例如,节点可以是 像这样复合子请求:

{
    "url" : "/services/data/v59.0/sobjects/Account/",
    "body" : {
        "name" : "Cloudy Consulting"
    },
    "method" : "POST",
    "referenceId" : "reference_id_account_1"
}

每个节点都有一个端点,表示 记录。

复合图形请求仅支持这些 URL。

网址支持的 HTTP 方法
/services/data/vXX.X/sobjects/sObject发布请参阅 sObject Basic 信息。
/services/data/vXX.X/sobjects/sObject/id删除、获取、修补请参见sObject 行。
/services/data/vXX.X/sobjects/sObject/customFieldName/externalId删除、获取、修补、发布请参见按外部 ID 划分的 sObject 行。

复合图可以定向,这意味着某些节点使用 来自其他节点的信息。例如,创建联系人的节点可以使用 用于将联系人与客户链接的 Account 节点的 ID。

为 例:

{
   "graphs": [{
      "graphId": "graph1",
      "compositeRequest": [{
            "body": {
               "name": "Cloudy Consulting"
            },
            "method": "POST",
            "referenceId": "reference_id_account_1",
            "url": "/services/data/v59.0/sobjects/Account/"
         },
         {
            "body": {
               "FirstName": "Nellie",
               "LastName": "Cashman",
               "AccountId": "@{reference_id_account_1.id}"
            },
            "method": "POST",
            "referenceId": "reference_id_contact_1",
            "url": "/services/data/v59.0/sobjects/Contact/"
         }
      ]
   }]
}

在 JSON 中定义复合图

复合图定义在 JSON是这样的:

{
    "graphId" : "graphId",
    graph
}

换句话说,像这样,每个都是复合子请求:

compositeSubrequest

{
    "graphId" : "graphId",
    "compositeRequest" : [
        compositeSubrequest,
        compositeSubrequest,
        ...
    ]
}

这些参数使您能够在查看响应时识别图形。他们需要 不能是数字,但它们必须遵循以下限制:

graphId

  • 它们在每个复合图操作中必须是唯一的。
  • 它们必须以字母数字字符开头。
  • 它们的长度必须少于 40 个字符。
  • 它们不能包含句点 (’.’)。

单个复合图请求可以使用一个或多个复合图。 请参阅使用复合图。

示例:创建客户、联系人、市场活动、商机、潜在顾客和 具有复合图请求的 CampaignMembers

此示例显示了执行以下操作的复合图:

  1. 创建帐户 1.
  2. 创建账户 2 作为账户 1 的子项。
  3. 创造:
    1. 联系人 1,链接到帐户 2。
    2. 联系人 2,向联系人 1 报告。
    3. 向联系人 2 报告的联系人 3。
  4. 创建广告系列。
  5. 创建一个链接到客户 2 和营销活动的机会。
  6. 创建潜在客户。
  7. 创建链接到潜在客户和营销活动的 CampaignMember。

此图的 JSON 为:

{
   "graphId" : "1",
   "compositeRequest" : [
      {
         "url" : "/services/data/v59.0/sobjects/Account/",
         "body" : {
           "name" : "Cloudy Consulting",
           "description" : "Parent account"
         },
         "method" : "POST",
         "referenceId" : "reference_id_account_1"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Account/",
         "body" : {
           "name" : "Easy Spaces",
           "description" : "Child account",
          ."ParentId" : "@{reference_id_account_1.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_account_2"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Contact/",
         "body" : {
           "FirstName" : "Sam",
           "LastName" : "Steele",
           "AccountId" : "@{reference_id_account_2.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_contact_1"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Contact/",
         "body" : {
           "FirstName" : "Charlie",
           "LastName" : "Dawson",
           "ReportsToId" : "@{reference_id_contact_1.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_contact_2"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Contact/",
         "body" : {
           "FirstName" : "Nellie",
           "LastName" : "Cashman",
           "ReportsToId" : "@{reference_id_contact_2.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_contact_3"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Campaign/",
         "body" : {
           "name" : "Spring Campaign"
         },
         "method" : "POST",
         "referenceId" : "reference_id_campaign"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Opportunity/",
         "body" : {
           "name" : "Opportunity",
           "stageName" : "Value Proposition",
           "closeDate" : "2025-12-31",
           "CampaignId" : "@{reference_id_campaign.id}",
           "AccountId" : "@{reference_id_account_2.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_opportunity"
      },
      {
         "url" : "/services/data/v59.0/sobjects/Lead/",
         "body" : {
           "FirstName" : "Belinda",
           "LastName" : "Mulroney",
           "Company" : "Klondike Quarry",
           "Email" : "bmulroney@example.com"
         },
         "method" : "POST",
         "referenceId" : "reference_id_lead"
      },
      {
         "url" : "/services/data/v59.0/sobjects/CampaignMember/",
         "body" : {
           "CampaignId" : "@{reference_id_campaign.id}",
           "LeadId" : "@{reference_id_lead.id}"
         },
         "method" : "POST",
         "referenceId" : "reference_id_campaignmember"
      }
    ]
}

示例:获取有关资源的详细信息,然后在复合图中使用它们 请求

此示例演示如何对资源使用 GET,然后使用该资源的属性 资源。

{
   "graphs" : [
      {
         "graphId" : "graph1",
         "compositeRequest" : [
            {
               "method" : "GET",
               "url" : "/services/data/v59.0/sobjects/Account/001R0000003fSRrIAM",
               "referenceId" : "refAccount"
            },
            {
               "body" : {
                  "name" : "Amazing opportunity for @{refAccount.Name}",
                  "StageName" : "Stage 1",
                  "CloseDate" : "2025-06-01T23:28:56.782Z",
                  "AccountId" : "@{refAccount.Id}"
               },
               "method" : "POST",
               "url" : "/services/data/v59.0/sobjects/Opportunity",
               "referenceId" : "newOpportunity"
            }
         ]
      }
   ]
}

图形深度

  • 没有父节点的节点被视为深度为 1。
  • 另一个节点的深度是图中最大边数 深度 1 到该节点。当一个节点之间出现边时,两个节点之间会出现边 使用来自另一个节点的属性(如 )。@{reference_account.id}

AllOrNone 参数

在标准复合材料中 操作,则对发生错误时发生的情况的唯一控制是参数。如果值为 ,则整个复合请求为 回滚。如果值为 ,则 执行不依赖于失败子请求的其余子请求。 不执行依赖子请求,这可能会导致已处理和 未处理的记录。allOrNonetruefalse

复合图的优点是,每个图都保证完成所有 子请求成功或完全回滚。换言之,该参数是隐式的 考虑用于每个图形。一个 复合图形请求从不会导致已处理和未处理的混合 记录。allOrNonetrue

为确保图形独立,请遵循以下规则。

  1. 一个图中的子请求不能引用另一个图中的子请求。
  2. 一个复合图操作中的每个图都必须是独立的。如果一个图形 无法成功处理,这不能阻止其他图形 操作。

最佳实践

一般做法是使图形尽可能小。例如,它更多 拥有 50 个具有 10 个节点的图形而不是具有 500 个节点的 1 个图形是有效的。 保持图形较小有两个优点:

  • 如果图形中的某个项目失败,则仅回滚该图形中的项目。这更容易 识别和处理较小图形中的错误。
  • 服务器可以更快、更多地处理多个更小的图形 有效。

示例:提交复合图作业

有关如何提交复合图作业的示例,请参阅使用复合图。

使用复合图

此示例演示如何使用复合图。它还演示了一个请求如何使用多个复合图。

  • 常规复合请求允许您执行一系列 REST API 单个调用中的请求。您可以将一个请求的输出用作 输入到后续请求中。
  • 复合图扩展了常规的复合请求,允许您将 复杂而完整的一系列相关对象和记录。
  • 复合图还使您能够确保一组给定请求中的步骤是 要么全部完成,要么全部未完成。如果使用此选项,则不会 必须检查哪些请求成功。
  • 常规复合请求的子请求限制为 25 个。复合图增加了这一点 限制为 500。

创建请求:

curl -X POST curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/graph -H "Authorization: Bearer token" -H "Content-Type: application/json" --data @data.json

其中,该文件包含 图。请求正文的一般格式为:data.json

{
  "graphs": [
    {
      "graphId": "graphId",
      "compositeRequest": [
        compositeSubrequest,
        compositeSubrequest,
        ...
      ]
    },
    {
      "graphId": "graphId",
      "compositeRequest": [
        compositeSubrequest,
        compositeSubrequest,
        ...
      ]
    },
    ...
  ]
}

其中 是复合子请求 结果。compositeSubrequest

例如,两个复合图形请求分别创建一个帐户,然后创建相关记录:

{
    "graphs" : [
        {
            "graphId" : "1",
            "compositeRequest" : [
                {
                    "url" : "/services/data/v59.0/sobjects/Account/",
                    "body" : {
                        "name" : "Cloudy Consulting"
                    },
                    "method" : "POST",
                    "referenceId" : "reference_id_account_1"
                },
                {
                    "url" : "/services/data/v59.0/sobjects/Contact/",
                    "body" : {
                        "FirstName" : "Nellie",
                        "LastName" : "Cashman",
                        "AccountId" : "@{reference_id_account_1.id}"
                    },
                    "method" : "POST",
                    "referenceId" : "reference_id_contact_1"
                },
                {
                    "url" : "/services/data/v59.0/sobjects/Opportunity/",
                    "body" : {
                        "CloseDate" : "2024-05-22",
                        "StageName" : "Prospecting",
                        "Name" : "Opportunity 1",
                        "AccountId" : "@{reference_id_account_1.id}"
                    },
                    "method" : "POST",
                    "referenceId" : "reference_id_opportunity_1"
                }
            ]
        },
        {
            "graphId" : "2",
            "compositeRequest" : [
                {
                    "url" : "/services/data/v59.0/sobjects/Account/",
                    "body" : {
                        "name" : "Easy Spaces"
                    },
                    "method" : "POST",
                    "referenceId" : "reference_id_account_2"
                },
                {
                    "url" : "/services/data/v59.0/sobjects/Contact/",
                    "body" : {
                        "FirstName" : "Charlie",
                        "LastName" : "Dawson",
                        "AccountId" : "@{reference_id_account_2.id}"
                    },
                    "method" : "POST",
                    "referenceId" : "reference_id_contact_2"
                }
            ]
        }
    ]
}

响应是:

{
   "graphs" : [
      {
         "graphId" : "1",
         "graphResponse" : {
            "compositeResponse" : [
               {
                  "body" : {
                     "id" : "001R00000064wc7IAA",
                     "success" : true,
                     "errors" : [ ]
                  },
                  "httpHeaders" : {
                     "Location" : "/services/data/v59.0/sobjects/Account/001R00000064wc7IAA"
                  },
                  "httpStatusCode" : 201,
                  "referenceId" : "reference_id_account_1"
               },
               {
                  "body" : {
                     "id" : "003R000000DDMlTIAX",
                     "success" : true,
                     "errors" : [ ]
                  },
                  "httpHeaders" : {
                     "Location" : "/services/data/v59.0/sobjects/Contact/003R000000DDMlTIAX"
                  },
                  "httpStatusCode" : 201,
                  "referenceId" : "reference_id_contact_1"
               },
               {
                  "body" : {
                     "id" : "006R0000003FPYxIAO",
                     "success" : true,
                     "errors" : [ ]
                  },
                  "httpHeaders" : {
                     "Location" : "/services/data/v59.0/sobjects/Opportunity/006R0000003FPYxIAO"
                  },
                  "httpStatusCode" : 201,
                  "referenceId" : "reference_id_opportunity_1"
               }
            ]
         },
         "isSuccessful" : true
      },
      {
         "graphId" : "2",
         "graphResponse" : {
            "compositeResponse" : [
               {
                  "body" : {
                     "id" : "001R00000064wc8IAA",
                     "success" : true,
                     "errors" : [ ]
                  },
                  "httpHeaders" : {
                     "Location" : "/services/data/v59.0/sobjects/Account/001R00000064wc8IAA"
                  },
                  "httpStatusCode" : 201,
                  "referenceId" : "reference_id_account_2"
               },
               {
                  "body" : {
                     "id" : "003R000000DDMlUIAX",
                     "success" : true,
                     "errors" : [ ]
                  },
                  "httpHeaders" : {
                     "Location" : "/services/data/v59.0/sobjects/Contact/003R000000DDMlUIAX"
                  },
                  "httpStatusCode" : 201,
                  "referenceId" : "reference_id_contact_2"
               }
            ]
         },
         "isSuccessful" : true
      }
   ]
}

有关更多信息,请参阅使用复合图。

allOrNone(全部或无)复合请求和集合请求中的参数

如果 Composite 请求使用 sObject 集合,则有两个或多个参数可以交互,一个在 Composite 请求上,另一个在 每个 sObject 集合子请求。

allOrNone

  • 如果 Composite 请求已设置为 ,则 all-or-none 行为也适用于每个 sObject 集合子请求,覆盖子请求中的值。allOrNonetrueallOrNone
  • 如果 Composite 请求已设置为 ,则每个 sObject Collections 子请求的行为 根据其值 .allOrNonefalseallOrNone

例如,考虑此作业会发生什么情况,其中复合请求包含两个项:sObject 集合请求和创建联系人的请求。sObject 的 集合请求尝试创建两个帐户,其中一个失败,因为已经存在具有相同信息的现有帐户。

POST https://MyDomainName.my.salesforce.com/services/data/v59.0/composite -H "Authorization: Bearer token"

{
   "allOrNone" : outerFlag,
   "collateSubrequests" : false,
   "compositeRequest" : [
      {
         "method" : "POST",
         "url" : "/services/data/v59.0/composite/sobjects",
         "body" : {
            "allOrNone" : innerFlag,
            "records" : [
               {
                  "attributes" : { "type" : "Account" },
                  "Name" : "Northern Trail Outfitters",
                  "BillingCity" : "San Francisco"
               },
               {
                  "attributes" : { "type" : "Account" },
                  "Name" : "Easy Spaces",
                  "BillingCity" : "Calgary"
               }
            ]
         },
         "referenceId" : "newAccounts"
      },
      {
         "method" : "POST",
         "url" : "/services/data/v59.0/sObject/Contact",
         "body" : {
                "FirstName" : "John",
                "LastName" : "Smith"
         },
         "referenceId" : "newContact"
      }
   ]
}

和参数是 either 或 ,这会导致四种可能的情况。outerFlaginnerFlagtruefalse

案例 1:outerFlag = false,innerFlag = false

在本例中,两个请求均未设置为 ,因此两者都未设置为 。 请求已回滚。一个帐户已创建,另一个帐户失败。allOrNonetrue

案例 2:outerFlag = false,innerFlag = true

在本例中,内部 sObject 集合请求已设置为 ,因此会回滚。外部 Composite 请求不会回滚。allOrNonetrue

案例 3:outerFlag = true,innerFlag = true

在这种情况下,两者 requests 已设置为 ,因此它们都会回滚。allOrNonetrue

案例 4:outerFlag = true,innerFlag = false响应正文 这种情况是:

{
   "compositeResponse" : [
      {
         "body" : [
            {
               "id" : "001R00000066cndIAA",
               "success" : true,
               "errors" : [ ]
            },
            {
               "success" : false,
               "errors" : [
                  {
                     "statusCode" : "DUPLICATES_DETECTED",
                     "message" : "Use one of these records?",
                     "fields" : [ ]
                  }
               ]
            }
         ],
         "httpHeaders" : { },
         "httpStatusCode" : 200,
         "referenceId" : "collection1"
      },
      {
         "body" : [
            {
               "errorCode" : "PROCESSING_HALTED",
               "message" : "The transaction was rolled back since another operation in the same transaction failed."
            }
         ],
         "httpHeaders" : { },
         "httpStatusCode" : 400,
         "referenceId" : "newContact"
      }
   ]
}

在 在这种情况下,内部 sObject 集合请求已设置为 ,因此不会立即回滚。 但是,外部 Composite 请求已设置为 因此会回滚,这也会回滚 内部 sObject 集合请求。allOrNonefalseallOrNonetrue

注意

即使响应 sObject Collections 请求的正文显示了第一个 Account 的创建,即 Composite 请求被回滚的事实 表示帐户创建已回滚。最终结果是不会创建新帐户。“success” : true

为 sObjects REST API 生成 OpenAPI 3.0 文档 (测试版)

在此测试版中,您可以为 sObjects REST API 生成 OpenAPI 文档。

注意

此功能是一项测试版服务。客户可自行决定是否试用此类测试版服务。对测试版服务的任何使用均受协议和条款中提供的适用测试版服务条款的约束。

使用此测试版功能,您可以生成一个 OpenAPI 文档,该文档表示 六个 sObjects REST 反映您的自定义和配置的 API 资源。

支持的版本

此测试版功能适用于启用了 API 的 Developer Edition、Partner Developer Edition、沙盒和临时组织。

关于文档

OpenAPI 文档遵循 OpenAPI 规范的 3.0.1 版。有关详细信息,请参阅 https://www.openapis.org。

注意

此测试版 OpenAPI 文档可能会发生变化。请勿基于此 OpenAPI 文档构建生产集成。

OpenAPI 文档涵盖的内容

本 OpenAPI 文档介绍了这些 REST API 资源,您可以使用这些资源来检索、创建和更新对象数据。

  1. /services/data/v59.0/sobjects
    • 列出数据的可用对象及其元数据。提供组织编码和查询中允许的最大批大小。
    • 请参阅描述 全球。
  2. /services/data/v59.0/sobjects/sObject
    • 描述指定对象的单个元数据。可以创建对象记录。例如,使用 GET 方法检索 Account 对象的元数据,或者 使用 POST 方法创建一个 Account 对象。
    • 请参阅 sObject Basic 信息。
  3. /services/data/v59.0/sobjects/{sObject}/describe
    • 描述 sObject 的所有级别的单个元数据
    • 请参阅 sObject 描述。
  4. /services/data/v59.0/sobjects/sObject/{id}
    • 根据指定的对象 ID 访问记录。检索、更新或删除记录。可以检索字段值。使用 GET 方法检索记录或字段, DELETE 方法用于删除记录,PATCH 方法用于更新记录。
    • 请参阅 sObject 行。
  5. /services/data/v59.0/sobjects/{sObject}/deleted
    • 检索 sObject 的时间跨度内单个已删除记录的列表
    • 请参阅 sObject 被删除。
  6. /services/data/vXX.X/sobjects/{sObject}/{id}/{blobField}
    • 从单个记录中检索指定的 blob 字段,并将其作为二进制数据返回
    • 请参阅 sObject Blob Get。

启用 Beta 版

若要启用此测试版,请按照下列步骤操作。您必须具有“修改所有数据”或“自定义应用程序”权限。

  1. 在“设置”的“快速查找”框中,输入 ,然后选择“用户界面”。User Interface
  2. 在“用户界面”页面上,选择“启用 Salesforce Platform REST API、OpenAPI 3.0 规范生成(测试版)”。注意选择此项表示您接受 协议和条款中提供的测试版服务条款。

生成 OpenAPI 文档

开启 beta 功能后,按照以下步骤生成 OpenAPI 文档。

  1. 发送 POST 请求 自https://MyDomainName.my.salesforce.com/services/data/vXX.X/async/specifications/oas3注意这 API 版本 56.0 中的过程与早期 API 版本中的过程进行了更改。此步骤现在使用 POST 请求而不是 GET 请求。中的 API 版本 此 POST 请求 必须为 54.0 或更高。XX.X如果服务器在处理请求时遇到错误,它会报告“失败”状态并返回 4xx 或 5xx 状态。请求正文必须是{ "resources" : [ selectors ] }哪里可以selectors
    • “*”(获取所有资源)
    • 或者,以下一个或多个选择器(仅获取 OpenAPI 文档的特定部分)
      • “/services/data/v59.0/sobjects”
      • “/services/data/v59.0/sobjects/sObject其中可以是您在组织中有权访问的任何标准或自定义对象的名称sObject
      • “/services/data/v59.0/sobjects/sObject/{id}”
      • “/services/data/v59.0/sobjects/sObject/deleted”
      • “/services/data/v59.0/sobjects/{sObject}/deleted”
      • “/services/data/v59.0/sobjects/sObject/describe”
      • “/services/data/v59.0/sobjects/{sObject}/describe”
      • “/services/data/v59.0/sobjects/{sObject}/{id}/{blobField}”
      注意{blobField}、 和 必须输入 按照字面。它们不是变量。{id}{sObject}注意不要在选择器的末尾添加尾部斜杠,例如,检索 无。“/services/data/v59.0/sobjects/”注意对于 和 选择器,可以使用字面名称或对象名称。对于所有对象,这些请求的响应正文都是相同的。/describe/deleted{sObject}注意中的 API 版本 选择器必须是最新版本 v59.0。(这确实 不需要与步骤 1 中的 POST 请求或步骤 3 中的 GET 请求相同。例如{ "resources" : ["*"] }{ "resources" : [ "/services/data/v59.0/sobjects", "/services/data/v59.0/sobjects/Contact", "/services/data/v59.0/sobjects/Lead", "/services/data/v59.0/sobjects/Lead/{id}", "/services/data/v59.0/sobjects/{sObject}/deleted", "/services/data/v59.0/sobjects/Account/describe", "/services/data/v59.0/sobjects/{sObject}/{id}/{blobField}" ] }
  2. 假设可以无错误地解析请求,则服务器使用 HTTP 状态代码 202 (Accepted) 和包含 URI 的 JSON 响应正文进行响应,您可以在其中获取 OpenAPI 文档。例如:HTTP/1.1 202 Accepted { "href" : "/v59.0/async/specifications/oas3/NTByUjAwMDAwMDAwMDBh" }此 URI 的最后一部分(在此示例中)是 OpenAPI 的定位器 ID 公文。NTByUjAwMDAwMDAwMDBh
  3. 将 GET 请求发送到追加了定位器 ID 的同一 URI。为 例:https://MyDomainName.my.salesforce.com/services/data/vXX.X/​async/​specifications/​oas3/​NTByUjAwMDAwMDAwMDBh这 此 GET 请求中的 API 版本必须为 54.0 或更高版本。XX.X
    1. 如果服务器尚未完成 OpenAPI 文档的准备工作,它将使用 202(已接受)状态代码和状态消息“未启动”或“正在进行”进行响应。为 例:HTTP/1.1 202 Accepted { "status" : "In Progress" }
    2. 如果服务器已完成,它将以 200 (OK) 状态进行响应,并在响应正文中返回 OpenAPI 文档。例如:HTTP/1.1 200 OK{ "openapi": "3.0.1", "info": { "title": "Lightning Platform REST API", "description": "REST API provides you with programmatic access to your data in Salesforce. The flexibility and scalability of REST API make it an excellent choice for integrating Salesforce into your applications and for performing complex operations on a large scale. You can use REST API tools to create, manipulate, and search data in Salesforce by sending HTTP requests to endpoints in Salesforce. Depending on where you send requests, you access and operate on different pieces of information, called resources. Resources include records, query results, metadata, and more. ", "version": "59.0 }, "servers": [ ... ], "security": [ ... ], "paths": { "/sobjects": { ... }, "/sobjects/Contact": { ... }, "/sobjects/Lead": { ... }, "/sobjects/Lead/{id}": { ... }, "/sobjects/{sObject}/deleted": { ... }, "/sobjects/{sObject}/describe": { ... }, "/sobjects/{sObject}/{id}/{blobField}": { ... } }, "components": { ... } }

生成 OpenAPI 文档后,可以在 48 小时内使用相同的定位器 ID 再次检索 OpenAPI 文档。48 小时后,使用该定位器 ID 将生成 404 (未找到)错误。

每个用户只能每 6 小时生成一个新的 OpenAPI 文档。如果您在最后一次通话后 6 小时内再次致电 生成,即使使用不同的请求正文,API 也会返回相同的定位器 ID。/async/specifications/oas3

如果选择的资源与任何受支持的资源都不匹配,或者选择的资源无权访问,则请求不会失败,但 OpenAPI 文档将不包含该资源,其路径在 OpenAPI 文档中将不可见。

提供反馈

要向我们提供反馈,请登录 Trailhead,然后加入 OpenAPI 规范 Salesforce REST API 开拓者社区。

您的反馈很有价值,可以帮助我们发现存在的问题并激发未来的变革。我们正在寻找一般印象、改进建议、错误和反馈 好吧,这个 OpenAPI 文档与您的 OpenAPI 用例保持一致。

使用搜索和查询

本节中的示例使用 REST API 资源来搜索和查询记录 使用 Salesforce 对象搜索语言 (SOSL) 和 Salesforce 对象查询语言 (SOQL),以及 其他搜索 API。有关 SOSL 和 SOQL 的详细信息,请参阅 SOQL 和 SOSL 参考

  • 执行 SOQL 查询 使用 Query 资源执行 SOQL 查询,该查询
    在单个响应中返回所有结果,或者如果需要,返回部分结果和用于检索其余结果的定位器。
  • 执行包含已删除项目的
    SOQL 查询 使用 QueryAll 资源执行 SOQL 查询,该查询包含有关因合并或删除而删除的记录的信息。使用 QueryAll 而不是 Query,因为 Query 资源将自动筛选出已删除的项。
  • 获取有关查询性能的反馈(测试版)
    要获取有关 Salesforce 如何执行查询、报表或列表视图的反馈,请使用 Query 资源和 explain 参数。Salesforce 会分析每个查询,以找到获取查询结果的最佳方法。根据查询和查询筛选器,Salesforce 使用索引或内部优化。要返回有关 Salesforce 如何优化查询的详细信息,而无需实际运行查询,请使用 explain 参数。根据响应,决定是否微调查询的性能,例如添加筛选器以使查询更具选择性。
  • 搜索字符串
    使用 Search 资源执行 SOSL 搜索,或使用 Parameterized Search 资源执行不带 SOSL 的简单 RESTful 搜索。
  • 获取默认搜索范围和顺序 使用“搜索范围和顺序”资源检索登录用户的默认全局搜索范围和顺序
    ,包括用户搜索结果页中的任何固定对象。
  • 获取对象的搜索结果布局 使用“搜索结果布局”资源检索查询字符串中指定的每个对象
    的搜索结果布局配置。
  • 查看相关项目 使用“相关项目
    ”资源获取相关记录的列表。

执行 SOQL 查询

使用 Query 资源执行 SOQL 查询,该查询在单个响应中返回所有结果,或者 如果需要,返回部分结果和用于检索剩余结果的定位器 结果。

以下查询请求所有 name 字段中的值 帐户记录。执行查询的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/?q=SELECT+name+from+Account -H "Authorization: Bearer token"

用于执行查询的示例请求正文不需要用于执行查询的示例响应正文

{
    "done" : true,
    "totalSize" : 14,
    "records" : 
    [ 
        {  
            "attributes" : 
            {    
                "type" : "Account",    
                "url" : "/services/data/v59.0/sobjects/Account/001D000000IRFmaIAH"  
            },  
            "Name" : "Test 1"
        }, 
        {  
            "attributes" : 
            {    
                "type" : "Account",    
                "url" : "/services/data/v59.0/sobjects/Account/001D000000IomazIAB"  
            },  
            "Name" : "Test 2"
        }, 

        ...

    ]
}

检索剩余的 SOQL 查询 结果

如果初始查询仅返回部分结果,则响应结束 包含一个名为 :

nextRecordsUrl

"nextRecordsUrl" : "/services/data/v59.0/query/01gD0000002HU6KIAW-2000"

在这种情况下,请求下一批记录并重复,直到所有记录都 被检索到。这些请求使用 ,并且不包含任何参数。nextRecordsUrl检索剩余查询结果的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/01gD0000002HU6KIAW-2000 -H "Authorization: Bearer token"

用于检索剩余查询结果的示例请求正文不需要用于检索剩余查询结果的示例响应正文

{
    "done" : true,
    "totalSize" : 3214,
    "records" : [...]
}

执行包含以下内容的 SOQL 查询 已删除的项目

使用 QueryAll 资源执行 SOQL 查询,其中包括 有关因合并或删除而删除的记录的信息。用 QueryAll 而不是 Query,因为 Query 资源将自动筛选掉 已删除的项目。

以下查询请求所有 Name 字段中的值 已删除的Merchandise__c记录,在具有一个已删除Merchandise__c的组织中 记录。使用 Query 而不是 QueryAll 的同一查询不会返回任何记录,因为 查询会自动从结果集中筛选出任何已删除的记录。对已删除的Merchandise__c记录执行查询的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/queryAll/?q=SELECT+Name+from+Merchandise__c+WHERE+isDeleted+=+TRUE -H "Authorization: Bearer token"

用于执行查询的示例请求正文不需要用于执行查询的示例响应正文

{
    "done" : true,
    "totalSize" : 1,
    "records" : 
    [ 
        {  
            "attributes" : 
            {    
                "type" : "Merchandise__c",    
                "url" : "/services/data/v59.0/sobjects/Merchandise__c/a00D0000008pQRAIX2"  
            },  
            "Name" : "Merchandise 1"
        }, 
    ]
}

检索剩余的 SOQL 查询 结果

如果初始查询仅返回部分结果,则响应的末尾将 包含一个名为 的字段。为 例如,您可能会在 查询:

nextRecordsUrl

"nextRecordsUrl" : "/services/data/v59.0/query/01gD0000002HU6KIAW-2000"

在这种情况下,请求下一批记录并重复,直到所有记录都 被检索到。这些请求使用 ,并且不包含任何参数。nextRecordsUrl

虽然有 URL 时,它仍会提供初始 QueryAll 请求的剩余结果。 其余结果包括与初始匹配的已删除记录 查询。nextRecordsUrlquery检索剩余结果的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/01gD0000002HU6KIAW-2000 -H "Authorization: Bearer token"

用于检索其余结果的示例请求正文不需要用于检索剩余结果的示例响应正文

{
    "done" : true,
    "totalSize" : 3214,
    "records" : [...]
}

获取有关查询性能的反馈(测试版)

要获取有关 Salesforce 如何执行查询、报告或列表视图的反馈,请使用 Query 资源以及 explain 参数。Salesforce 会分析每个查询以找到最佳查询 方法获取查询结果。根据查询和查询筛选器,Salesforce 使用索引或内部优化。要返回有关 Salesforce 如何优化 query,而不实际运行查询,使用 explain 参数。 根据响应,决定是否微调查询的性能,例如添加 筛选器,使查询更具选择性。

注意

此功能是一项测试版服务。客户可以选择单独试用此类测试版服务 自由裁量权。对测试版服务的任何使用均受适用的测试版服务条款的约束 在协议和条款中提供。

响应包含一个或多个查询执行计划,按从最优到最少的顺序排序 最佳的。最佳计划是当查询、报表或列表视图为 执行。

有关使用 explain 时返回的字段的更多详细信息,请参阅查询选项标头中的 explain 参数。查看更多 有关使查询更具选择性的信息,请参阅使用超大型 SOQL 《Apex 开发人员指南》中的查询。

示例:对查询性能的反馈

以下性能反馈查询使用:Merchandise__c

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/?explain=
SELECT+Name+FROM+Merchandise__c+WHERE+CreatedDate+=+TODAY+AND+Price__c+>+10.0

性能反馈查询的响应正文如下所示:

{
  "plans" : [ {
    "cardinality" : 1,
    "fields" : [ "CreatedDate" ],
    "leadingOperationType" : "Index",
    "notes" :  [ {
      "description" : "Not considering filter for optimization because unindexed",
      "fields" : [ "IsDeleted" ],
      "tableEnumOrId" : "Merchandise__c"
    } ],
    "relativeCost" : 0.0,
    "sobjectCardinality" : 3,
    "sobjectType" : "Merchandise__c"
  }, {
    "cardinality" : 1,
    "fields" : [ ],
    "leadingOperationType" : "TableScan",
    "notes" :  [ {
      "description" : "Not considering filter for optimization because unindexed",
      "fields" : [ "IsDeleted" ],
      "tableEnumOrId" : "Merchandise__c"
    } ],
    "relativeCost" : 0.65,
    "sobjectCardinality" : 3,
    "sobjectType" : "Merchandise__c"
  } ]
}

此响应表明 Salesforce 为此查询找到了两个可能的执行计划。 第一个计划使用 CreatedDate 索引字段来提高此查询的性能。 第二个计划在不使用索引的情况下扫描所有记录。如果执行查询,则 使用第一个计划。这两个计划都指出,没有用于过滤的二次优化 标记为已删除的记录,因为 IsDeleted 字段未编制索引。

搜索字符串

使用搜索资源执行 SOSL 搜索或使用 参数化搜索资源,用于执行简单的 RESTful 搜索,而无需 SOSL的。

SOSL 示例 使用 GET 方法进行搜索

以下示例执行 SOSL 搜索。此示例中的搜索字符串必须经过 URL 编码。

Acme示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/search/?q=FIND+%7BAcme%7D -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
  "searchRecords" : [ {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IqhSLIAZ"
    },
    "Id" : "001D000000IqhSLIAZ",
  }, {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IomazIAB"
    },
    "Id" : "001D000000IomazIAB",
  } ]
}

使用 GET 方法的参数化搜索示例

以下示例 执行对 的参数化搜索。这 此示例中的搜索字符串必须经过 URL 编码。

Acme示例用法对包含 Acme 的所有结果进行全局搜索

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/parameterizedSearch/?q=Acme -H "Authorization: Bearer token"

帐户搜索包含 Acme 的结果,返回 id 和 名称字段

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/parameterizedSearch/?q=Acme&sobject=Account&Account.fields=id,name&Account.limit=10 -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
  "searchRecords" : [ {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IqhSLIAZ"
    },
    "Id" : "001D000000IqhSLIAZ"
  }, {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IomazIAB"
    },
    "Id" : "001D000000IomazIAB"
  } ]
}

具有元数据参数的示例响应正文

注意

仅当 请求指定 。metadata=LABELS

{
  "searchRecords" : [ {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IqhSLIAZ"
    },
    "Id" : "001D000000IqhSLIAZ",
  }, {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001D000000IomazIAB"
    },
    "Id" : "001D000000IomazIAB",
  } ],
  "metadata" : {
    "entityetadata" : [ {
      "entityName" : "Account",
      "fieldMetadata" : [ {

        "name" : "Name",
        "label" : "Account Name"
       } ]
    } ]
  }
}

使用 POST 方法的参数化搜索示例

执行一个 使用 POST 方法进行参数化搜索,以访问所有可用的搜索功能。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/parameterizedSearch "Authorization: Bearer token" -H "Content-Type: application/json” -d "@search.json”

示例请求正文不需要示例 JSON 文件

{
    "q":"Smith",
    "fields" : ["id", "firstName", "lastName"],
    "sobjects":[{"fields":["id", "NumberOfEmployees"],
	          "name": "Account", 
	          "limit":20},
	         {"name": "Contact"}],
    "in":"ALL",
    "overallLimit":100,
    "defaultLimit":10
}

示例响应正文

{
  "searchRecords" : [ {
    "attributes" : {
      "type" : "Contact",
      "url" : "/services/data/v59.0/sobjects/Contact/003xx000004TraiAAC"
    },
    "Id" : "003xx000004TraiAAC",
    "FirstName" : "Smith",
    "LastName" : "Johnson"
  }, {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v59.0/sobjects/Account/001xx000003DHXnAAO"
    },
    "Id" : "001xx000003DHXnAAO",
    "NumberOfEmployees" : 100
  } ]
}

另见

  • 搜索
  • 参数化搜索

获取默认搜索范围和顺序

使用“搜索范围和顺序”资源检索 已登录用户,包括用户搜索结果中的任何固定对象 页。

在以下示例中,登录用户的默认全局搜索范围包括 网站、想法、案例、商机、客户和用户对象,按以下顺序排列 它们在响应正文中返回。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/search/scopeOrder -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

[
  {
    "type":"Site",
    "url":"/services/data/v59.0/sobjects/Site/describe"
  },
  {
    "type":"Idea",
    "url":"/services/data/v59.0/sobjects/Idea/describe"
  },
  {
    "type":"Case",
    "url":"/services/data/v59.0/sobjects/Case/describe"
  },
  {
    "type":"Opportunity",
    "url":"/services/data/v59.0/sobjects/Opportunity/describe"
  },
  {
    "type":"Account",
    "url":"/services/data/v59.0/sobjects/Account/describe"
  },
  {
    "type":"User",
    "url":"/services/data/v59.0/sobjects/User/describe"
  }
]

获取对象的搜索结果布局

使用“搜索结果布局”资源检索每个对象的搜索结果布局配置 在查询字符串中指定。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/search/layout/?q=Account,Contact,Lead,Asset "Authorization: Bearer token"

示例请求正文不需要示例响应正文

[ { "label" : "Search Results",
    "limitRows" : 25,
    "searchColumns" : [ { "field" : "Account.Name",
          "format" : null,
          "label" : "Account Name",
          "name" : "Name"
        },
        { "field" : "Account.Site",
          "format" : null,
          "label" : "Account Site",
          "name" : "Site"
        },
        { "field" : "Account.Phone",
          "format" : null,
          "label" : "Phone",
          "name" : "Phone"
        },
        { "field" : "User.Alias",
          "format" : null,
          "label" : "Account Owner Alias",
          "name" : "Owner.Alias"
        }
      ]
  },
  { "label" : "Search Results",
    "limitRows" : 25,
    "searchColumns" : [ { "field" : "Contact.Name",
          "format" : null,
          "label" : "Name",
          "name" : "Name"
        },
        { "field" : "Account.Name",
          "format" : null,
          "label" : "Account Name",
          "name" : "Account.Name"
        },
        { "field" : "Account.Site",
          "format" : null,
          "label" : "Account Site",
          "name" : "Account.Site"
        },
        { "field" : "Contact.Phone",
          "format" : null,
          "label" : "Phone",
          "name" : "Phone"
        },
        { "field" : "Contact.Email",
          "format" : null,
          "label" : "Email",
          "name" : "Email"
        },
        { "field" : "User.Alias",
          "format" : null,
          "label" : "Contact Owner Alias",
          "name" : "Owner.Alias"
        }
      ]
  },
  { "label" : "Search Results",
    "limitRows" : 25,
    "searchColumns" : [ { "field" : "Lead.Name",
          "format" : null,
          "label" : "Name",
          "name" : "Name"
        },
        { "field" : "Lead.Title",
          "format" : null,
          "label" : "Title",
          "name" : "Title"
        },
        { "field" : "Lead.Phone",
          "format" : null,
          "label" : "Phone",
          "name" : "Phone"
        },
        { "field" : "Lead.Company",
          "format" : null,
          "label" : "Company",
          "name" : "Company"
        },
        { "field" : "Lead.Email",
          "format" : null,
          "label" : "Email",
          "name" : "Email"
        },
        { "field" : "Lead.Status",
          "format" : null,
          "label" : "Lead Status",
          "name" : "toLabel(Status)"
        },
        { "field" : "Name.Alias",
          "format" : null,
          "label" : "Owner Alias",
          "name" : "Owner.Alias"
        }
      ]
  },
]

查看相关项目

使用“相关项目”资源获取相关项目列表 记录。获取当前用户最相关列表的示例用法 记录

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/relevantItems -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

[ {
    "apiName" : "Contact",
    "key" : "003",
    "label" : "Contacts",
    "lastUpdatedId" : "135866748",
    "recordIds" : [ "003xx000004TxBA" ]
}, {   "apiName" : "Account",
    "key" : "001",
    "label" : "Accounts",
    "lastUpdatedId" : "193640553",
    "recordIds" : [ "001xx000003DWsT" ]
}, {
    "apiName" : "User",
    "key" : "005",
    "label" : "Users",
    "lastUpdatedId" : "-199920321",
    "recordIds" : [ "005xx000001Svqw", "005xx000001SvwK", "005xx000001SvwA" ]
}, {  "apiName" : "Case",
    "key" : "069",
    "label" : "Cases",
    "lastUpdatedId" : "1033471693",
    "recordIds" : [ "069xx0000000006", "069xx0000000001", "069xx0000000002" ]
} ]

筛选对特定对象的响应的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/relevantItems?sobjects=Account,User -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

[ {
    "apiName" : "Account",
    "key" : "001",
    "label" : "Accounts",
    "lastUpdatedId" : "193640553",
    "recordIds" : [ "001xx000003DWsT" ]
}, {
  "apiName" : "User",
    "key" : "005",
    "label" : "Users",
    "lastUpdatedId" : "102959935",
    "recordIds" : [ "005xx000001Svqw", "005xx000001SvwK", "005xx000001SvwA" ]
} ]

将用户的当前相关记录列表与 以前的版本

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/relevantItems?lastUpdatedId=102959935 -H "Authorization: Bearer token"

示例请求正文不需要示例响应标头

lastUpdatedId: 102959935
newResultSetSinceLastQuery: true

示例响应正文

[ {
    "apiName" : "User",
    "key" : "003",
    "label" : "Users",
    "lastUpdatedId" : "102959935",
    "recordIds" : [ "003xx000004TxBA" ]
}, {
    "apiName" : "Account",
    "key" : "001",
    "label" : "Accounts",
    "lastUpdatedId" : "193640553",
    "recordIds" : [ "001xx000003DWsT" ]
}, {
    "apiName" : "Case",
    "key" : "005",
    "label" : "Cases",
  "lastUpdatedId" : "1740766611",
    "recordIds" : [ "005xx000001Svqw", "005xx000001SvwA" ]
} ]

将用户的当前相关记录列表与 特定对象的先前版本

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/relevantItems?mode=MRU&sobjects=Account,Contact&Account.lastUpdatedId=102959935 -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

[ {
    "apiName" : "Account",
    "key" : "001",
    "label" : "Accounts",
    "lastUpdatedId" : "193640553",
    "recordIds" : [ "001xx000003DWsT" ]
} ]

另见

  • sObject 相关项目

删除 Lightning Experience 事件系列

使用 HTTP DELETE 方法删除序列中的一个或多个 IsRecurrence2 事件。你 可以删除单个事件、特定事件之后的所有事件(包括特定事件)或整个事件 系列。

删除序列中的单个事件

使用 sObject Rows 资源删除事件记录。删除 系列中,指定事件 ID 并使用资源来删除记录。

从系列中删除多个事件或所有事件

若要删除序列中特定事件及以后的所有事件,请指定事件 ID 并使用资源的 DELETE 方法删除记录。调用此方法时, IsRecurrence2 必须为 true,IsRecurrence2Exclusion 必须为 false。

若要删除整个事件系列,请指定该系列中第一个事件的事件 ID 并使用资源的 DELETE 方法删除记录。从系列中删除多个事件或所有事件的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Event/00Uxx0000000000/fromThisEventOnwards -H "Authorization: Bearer token" -X DELETE

示例请求正文

None needed

成功删除事件后的示例响应正文

{
success: We’re deleting the selected events from the series. Wait for all events to be removed. 
}

考虑

从事件中删除不支持来自以下事件的调用:

  • 发生在 Recurrence2PatternStartDate 的原始值之前。
  • 定义为子事件。

如果事件系列源自 Salesforce 外部,并且事件 ID 为第一次 不可用,则无法删除系列中的所有事件。相反,请从特定 发生。

从富文本区域字段获取图像

使用 sObject 富文本图像获取资源从富文本区域字段中检索图像。在这个例子中,我们 从名为 的潜在客户记录的自定义富文本字段中检索图像。我们假设图像已经 上传到此字段。

LeadPhotoRichText__c

获取镜像引用 ID

在通过请求检索图像之前,必须先从富文本字段中获取图像。使用 sObject Rows 资源检索 潜在顾客记录的字段信息。refid

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Lead/00Q112222233333 -H "Authorization: Bearer token"

下面是请求的精简输出示例。

{
    "attributes": {
        "type": "Lead",
        "url": "/services/data/v51.0/sobjects/Lead/00Q112222233333"
    },
    "Id": "00Q112222233333",
    "IsDeleted": false,
    "MasterRecordId": null,
    "LastName": "Smith",
    "FirstName": "John",

    ...

    "LeadPhotoRichText__c": "<img alt=\"johnSmithPhoto\" src=\"https://MyDomainName.documentforce.com/servlet/rtaImage?eid=a005e000007Dksm&amp;feoid=00N5e00000djU6Y&amp;refid=0EM5e000000B9LQ\"></img>"
}

从LeadPhotoRichText__c字段中可以看出,图像的 是 。使用这个 值以检索图像。refid0EM5e000000B9LQ

检索图像

使用潜在顾客记录 ID、富文本字段名称和图像检索图像。响应将图像作为编码数据返回,并使用 与上传时使用的文件类型相同。将返回的数据另存为图像文件,并使用 使用参数的适当文件类型。refid–output filename

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Lead/00Q112222233333/richTextImageFields/LeadPhotoRichText__c/0EMR00000000A8V -H "Authorization: Bearer token" --output "LeadPhoto.jpeg"

插入或更新 Blob 数据

您可以使用 sObject 基本信息、sObject 行或 sObject 要在其中插入或更新二进制大型对象 (blob) 的集合资源 Salesforce,例如图像或 PDF。您可以将任何类型的文件或二进制数据上传到 包含 blob 字段的任何标准对象。

若要插入和更新 blob 数据,请创建多部分请求正文。第一部分 请求正文包含非二进制字段数据,例如新字段的描述或名称 记录。第二部分包含您要上传的文件的二进制数据。这 请求正文必须符合 MIME 多部分内容类型标准。查看更多 信息,请参阅多部分内容类型的 W3C 标准。

如果使用 sObject 基本信息或 sObject 行资源,则 ContentVersion 对象和 对于所有其他符合条件的标准对象,为 500 MB。如果使用 sObject 集合 资源,则单个请求中所有文件的最大总大小为 500 MB。

注意

可以使用非多部分消息插入或更新 blob 数据,但受到限制 到 50 MB 的文本数据或 37.5 MB 的 base64 编码数据。

这些部分提供了如何使用多部分插入或更新 blob 数据的示例 content-type 请求。这些示例的请求正文使用 JSON 格式。

插入包含 Blob 数据的文档

此示例请求和请求正文创建一个 Document 记录,其中包含 PDF 文件的二进制数据。除了文件本身的二进制数据外, request body 还指定其他字段数据,包括 Document 对象所需的 FolderId。

如果您在 Salesforce 中没有新文档记录的文件夹记录,则必须 使用 sObject 基本信息资源创建一个,然后才能遵循此操作 例。确保“文件夹”记录的“类型”字段为 公文。

提示

成功发送请求后,您可以查看新文档 在 Salesforce Classic 中。Salesforce Lightning 不会在用户中显示文档 接口。创建文档的示例请求

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Document/ -H "Authorization: Bearer token" -H "Content-Type: multipart/form-data; boundary=\"boundary_string\"" --data-binary @NewDocument.json

用于创建文档的示例请求正文此请求正文表示 NewDocument.json 的内容。PDF 的二进制数据 为简洁起见,省略了内容,并替换为“二进制数据” 去这里。实际请求包含完整的二进制文件 内容。

--boundary_string
Content-Disposition: form-data; name="entity_document";
Content-Type: application/json

{  
    "Description" : "Marketing brochure for Q1 2011",
    "Keywords" : "marketing,sales,update",
    "FolderId" : "005D0000001GiU7",
    "Name" : "Marketing Brochure Q1",
    "Type" : "pdf"
}

--boundary_string
Content-Type: application/pdf
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf"

Binary data goes here.

--boundary_string--

示例响应正文成功后,新文档的 ID 为 返回。

{
    "id" : "015D0000000N3ZZIA0",
    "errors" : [ ],
    "success" : true
}

错误响应示例

{
    "fields" : [ "FolderId" ],
    "message" : "Folder ID: id value of incorrect type: 005D0000001GiU7",
    "errorCode" : "MALFORMED_ID"
}

使用 Blob 数据更新文档

本示例更新现有 Document 记录。根据 请求正文,可以更新记录的字段,关联二进制数据 有了它,或两者兼而有之。

如果只想更新记录字段,则请求正文不需要 多部分内容类型。更新 Document 对象中的二进制数据的示例请求

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/Document/015D0000000N3ZZIA0 -H "Authorization: Bearer token" -H "Content-Type: multipart/form-data; boundary=\"boundary_string\"" --data-binary @UpdateDocument.json -X PATCH

用于更新 Document 对象中的二进制数据的示例请求正文

此请求正文表示 UpdateDocument.json 的内容。此示例更新 记录的二进制数据,以及“名称”和“关键字”字段。如果您只想更新 二进制数据,您可以删除带有 Name 和 Keywords 字段的代码行。

为简洁起见,省略了 PDF 内容的二进制数据,并且 替换为“更新的文档二进制文件转到此处”。一 实际请求包含完整的二进制内容。

--boundary_string
Content-Disposition: form-data; name="entity_content";
Content-Type: application/json

{  
    "Name" : "Marketing Brochure Q1 - Sales",
    "Keywords" : "sales, marketing, first quarter"
}

--boundary_string
Content-Type: application/pdf
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf"

Updated document binary data goes here.

--boundary_string--

用于更新 Document 对象中的字段的示例响应正文无返回错误响应请参阅状态代码和错误响应。

插入 ContentVersion

此示例插入一个新的 ContentVersion。除了文件的二进制数据 本身,此代码还为其他字段(如 ReasonForChange 和 PathOnClient)提供值。这 message 包含 ContentDocumentId,因为 ContentVersion 始终与 ContentDocument 相关联。

提示

ContentVersion 对象不支持更新。因此,你不能 更新 ContentVersion。您只能插入新的 ContentVersion。您可以看到 内容选项卡上的更改结果。插入 ContentVersion 的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/ContentVersion -H "Authorization: Bearer token" -H "Content-Type: multipart/form-data; boundary=\"boundary_string\"" --data-binary @NewContentVersion.json

用于插入 ContentVersion 的示例请求正文

此请求正文表示文件 NewContentVersion.json 的内容。二进制数据 为简洁起见,省略了 PDF 内容,并替换为 “二进制数据在这里。”实际请求包含 完整的二进制内容。

--boundary_string
Content-Disposition: form-data; name="entity_content";
Content-Type: application/json

{
    "ContentDocumentId" : "069D00000000so2",
    "ReasonForChange" : "Marketing materials updated",
    "PathOnClient" : "Q1 Sales Brochure.pdf"
}

--boundary_string
Content-Type: application/octet-stream
Content-Disposition: form-data; name="VersionData"; filename="Q1 Sales Brochure.pdf"

Binary data goes here.

--boundary_string--

插入 ContentVersion 的示例响应正文

{
    "id" : "068D00000000pgOIAQ",
    "errors" : [ ],
    "success" : true
}

插入 ContentVersion 的错误响应请参阅状态代码和错误响应。

使用 sObject 集合插入 Blob 记录的集合

本示例插入新文档的集合。除了二进制数据 文件本身,此代码还指定其他字段数据,例如每条记录的 Description 和 Name 在集合中。

提示

成功发送请求后,您可以查看新文档 在 Salesforce Classic 中。Salesforce Lightning 不会在用户中显示文档 接口。属性如果将 sObject 集合用于 blob 数据,则必须指定某些 除 in 之外的属性值 请求正文的属性映射。type

参数描述
binaryPartName对于 blob 数据是必需的。的唯一标识符 二进制部分。
binaryPartName别名对于 blob 数据是必需的。中字段的名称 插入或更新二进制数据。

创建文档的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/composite/sobjects/ -H "Authorization: Bearer token" -H "Content-Type: multipart/form-data; boundary=\"boundary_string\"" --data-binary @newdocuments.json

用于创建文档的示例请求正文此代码是 newdocuments.json 的内容。这 为简洁起见,省略了 PDF 内容的二进制数据并进行了替换 替换为“二进制数据在这里”。实际请求包含 完整二进制 内容。

--boundary_string
Content-Disposition: form-data; name="collection"
Content-Type: application/json

{
    "allOrNone" : false,
    "records" :
    [
        {
            "attributes" :
            {
                "type" : "Document",
                "binaryPartName": "binaryPart1",
                "binaryPartNameAlias": "Body"
            },
            "Description" : "Marketing Brochure",
            "FolderId" : "005xx000001Svs4AAC",
            "Name" : "Brochure",
            "Type" : "pdf"
        },
        {
            "attributes" :
            {
                "type" : "Document",
                "binaryPartName": "binaryPart2",
                "binaryPartNameAlias": "Body"
            },
            "Description" : "Pricing Overview",
            "FolderId" : "005xx000001Svs4AAC",
            "Name" : "Pricing",
            "Type" : "pdf"
        }
    ]
}

--boundary_string
Content-Disposition: form-data; name="binaryPart1"; filename="Brochure.pdf"
Content-Type: application/pdf

Binary data goes here.

--boundary_string
Content-Disposition: form-data; name="binaryPart2"; filename="Pricing.pdf"
Content-Type: application/pdf

Binary data goes here.

--boundary_string--

用于创建文档的示例响应正文成功后,新文档的 ID 为 返回。

[
    {
        "id": "015xx00000013QjAAI",
        "errors": [],
        "success": true
    },
    {
        "id": "015xx00000013QkAAI",
        "errors": [],
        "success": true
    }
]

有关更多信息,请参见 sObject 集合。

多部分消息注意事项

以下是多部分消息格式的一些注意事项,当您 插入或更新 blob 数据。边界字符串

  • 分隔多部分请求正文的各个部分。
  • 必须在分段请求的标头中指定。Content-Type
  • 最多可包含 70 个字符。
  • 不能是出现在 请求正文。
  • 包括第一个边界的两个连字符 (–) 前缀 字符串。
  • 包括最后一个边界字符串的两个连字符 (–) 后缀。

Content-Disposition 标头

  • 在请求正文的每个部分中是必需的。
  • 必须作为值 和属性。form-dataname
    • 在请求正文的非二进制部分,使用任何值 对于属性。name
    • 对于单个文档,在请求的二进制部分 body,请使用该属性指定 对象。例如,blob 数据字段的名称 Document 对象是 Body。name
    • 对于使用 sObject 集合插入或更新的文档, 使用属性 在请求正文的每个二进制部分指定一个唯一的 该部件的标识符。引用这些标识符 由请求正文的非二进制部分。name
  • 必须包含二进制部分的属性,该属性表示本地 文件。filename

Content-Type 标头

  • 在多部分请求正文的每个部分中是必需的。
  • 支持 和 内容 多部分请求正文的非二进制部分的类型。application/jsonapplication/xml
  • 支持多部分的二进制部分的任何内容类型 请求正文。

新行必须在标题和数据之间添加一个新行,用于 多部分请求正文。正如您在示例中看到的,一个新行 将 和 标头与 JSON 分开 或二进制数据。Content-TypeContent-Disposition

另见

  • sObject基本信息
  • sObject 行
  • sObject 集合
  • 获取 Blob 数据

获取 Blob 数据

使用 sObject Blob Get 资源获取 给定记录。若要获取 blob 数据,必须存在包含 blob 数据的记录 Salesforce的。

只有某些标准对象具有 blob 字段,例如 Attachment、ContentNote、 ContentVersion、Document、Folder 和 Note。

注意

sObject Blob Get 资源与复合 API 请求不兼容,因为它 返回二进制数据,而不是 JSON 或 XML 格式的数据。相反,请创建单个 sObject Blob 获取检索 blob 数据的请求。

以下示例获取在“插入或更新 Blob 数据”中创建的文档记录的 blob 数据。

从文档记录中检索 blob 数据的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Document/015D0000000N3ZZIA0/body -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文文档正文内容以二进制形式返回。响应内容类型不是 JSON 或 XML,因为返回的数据是二进制的。您可以将返回的二进制数据保存到一个文件中 存储和访问它。

REST例子

本部分提供了使用 REST API 资源执行各种不同任务的示例。 包括使用对象、组织信息和查询。

有关 REST API 资源的完整参考信息,请参阅参考。

  1. 获取有关我的组织
    的信息 本节中的示例使用 REST API 资源来检索组织级别的信息,例如组织中所有可用对象的列表。
  2. 使用对象元数据
    本节中的示例使用 REST API 资源来检索对象元数据信息。有关修改或创建对象元数据信息的信息,请参阅《元数据 API 开发人员指南》。
  3. 使用记录
    本节中的示例使用 REST API 资源创建、检索、更新和删除记录,以及其他与记录相关的操作。
  4. 删除 Lightning Experience 事件系列 使用 HTTP DELETE 方法删除系列
    中的一个或多个 IsRecurrence2 事件。您可以删除单个事件、特定事件之后的所有事件(包括特定事件)或整个事件系列。
  5. 使用搜索和查询
    本节中的示例使用 REST API 资源通过 Salesforce 对象搜索语言 (SOSL) 和 Salesforce 对象查询语言 (SOQL) 以及其他搜索 API 来搜索和查询记录。有关 SOSL 和 SOQL 的详细信息,请参阅 SOQL 和 SOSL 参考。
  6. 从富文本区域字段中
    获取图像 使用 sObject 富文本图像获取资源从富文本区域字段中检索图像。在此示例中,我们从名为 的潜在客户记录的自定义富文本字段中检索图像。我们假设图像已经上传到此字段。LeadPhotoRichText__c
  7. 插入或更新 Blob 数据
    您可以使用 sObject 基本信息、sObject 行或 sObject 集合资源在 Salesforce 中插入或更新二进制大型对象 (Blob),例如图像或 PDF。可以将任何类型的文件或二进制数据上载到包含 blob 字段的任何标准对象。
  8. 获取 Blob 数据 使用 sObject Blob Get 资源获取给定记录的 Blob 数据
    。若要获取 blob 数据,Salesforce 中必须存在包含 blob 数据的记录。
  9. 使用最近查看的信息
    本节中的示例使用 REST API 查询和最近查看的资源以编程方式检索和更新最近查看的记录信息。
  10. 管理用户密码
    本节中的示例使用 REST API 资源来管理用户密码,例如设置或重置密码。
  11. 使用审批流程和流程规则
    本节中的示例使用 REST API 资源来处理审批流程和流程规则。
  12. 使用事件监视
    这些示例使用 REST API 事件监视数据,其中包含可用于评估组织使用趋势和用户行为的信息。事件监控可通过 Lightning 平台 SOAP API 和 REST API 通过 EventLogFile 对象进行访问。因此,您可以将日志数据与自己的后端存储和数据集市集成,以关联来自多个组织和不同系统的数据。
  13. 使用复合资源 本节中的示例使用复合资源
    通过最大程度地减少客户端和服务器之间的往返次数来提高应用程序的性能。

获取有关我的组织的信息

本节中的示例使用 REST API 资源来检索组织级别 信息,例如组织中所有可用对象的列表。

  • 列出可用的 REST API 版本 使用“版本”资源列出有关当前可用的每个 REST API 版本的摘要信息,包括版本、标签和指向每个版本
    根目录的链接。无需身份验证即可检索版本列表。
  • 列出组织限制 使用“限制”资源列出组织限制
  • 列出可用的 REST 资源 使用 *** 资源列出可用于指定 API 版本的资源
    。这将提供每个附加资源的名称和 URI。
  • 获取对象列表 使用“描述全局”资源列出组织中可用且可供登录用户使用的对象
    。此资源还返回组织编码,以及查询中允许的最大批大小。
  • 获取元数据已更改
    时的对象列表 使用 Describe Global 资源和 HTTP 标头确定对象的元数据是否已更改。If-Modified-Since

列出可用的 REST API 版本

使用“版本”资源列出摘要信息 关于当前可用的每个 REST API 版本,包括版本、标签和 链接到每个版本的根目录。您不需要身份验证即可检索 版本。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/ -H "Authorization: Bearer token"

示例请求正文不需要示例 JSON 响应正文

[
    {
        "label" : "Spring '11",
        "url" : "/services/data/v21.0",
        "version" : "21.0"
    },
    {
        "label" : "Summer '11",
        "url" : "/services/data/v22.0",
        "version" : "22.0"
    },
    {
        "label" : "Winter '12",
        "url" : "/services/data/v23.0",
        "version" : "23.0"
    }
    ...
]

示例 XML 响应正文

<?xml version="1.0" encoding="UTF-8"?>
<Versions>
    <Version>
        <label>Spring &apos;11</label>
        <url>/services/data/v21.0</url>
        <version>21.0</version>
    </Version>
    <Version>
        <label>Summer &apos;11</label>
        <url>/services/data/v22.0</url>
        <version>22.0</version>
    </Version><Version>
        <label>Winter &apos;12</label>
        <url>/services/data/v23.0</url>
        <version>23.0</version>
    </Version>
    ...
</Versions>

列出组织限制

使用“限制”资源列出组织限制。

  • Max是组织的限制。
  • Remaining是调用或事件的数量 留给组织。

示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/limits/ -H "Authorization: Bearer token" -H "X-PrettyPrint:1"

示例请求正文不需要示例响应正文

{
    "ActiveScratchOrgs": {
        "Max": 3,
        "Remaining": 3
    },
    "AnalyticsExternalDataSizeMB": {
        "Max": 40960,
        "Remaining": 40960
    },
    "ConcurrentAsyncGetReportInstances": {
        "Max": 200,
        "Remaining": 200
    },
    "ConcurrentEinsteinDataInsightsStoryCreation": {
        "Max": 5,
        "Remaining": 5
    },
    "ConcurrentEinsteinDiscoveryStoryCreation": {
        "Max": 2,
        "Remaining": 2
    },
    "ConcurrentSyncReportRuns": {
        "Max": 20,
        "Remaining": 20
    },
    "DailyAnalyticsDataflowJobExecutions": {
        "Max": 60,
        "Remaining": 60
    },
    "DailyAnalyticsUploadedFilesSizeMB": {
        "Max": 51200,
        "Remaining": 51200
    },
    "DailyFunctionsApiCallLimit" : {
      "Max" : 235000,
      "Remaining" : 235000
    },
    "DailyApiRequests": {
        "Max": 5000,
        "Remaining": 4937
    },
    "DailyAsyncApexExecutions": {
        "Max": 250000,
        "Remaining": 250000
    },
    "DailyAsyncApexTests": {
        "Max": 500,
        "Remaining": 500
    },
    "DailyBulkApiBatches": {
        "Max": 15000,
        "Remaining": 15000
    },
    "DailyBulkV2QueryFileStorageMB": {
        "Max": 976562,
        "Remaining": 976562
    },
    "DailyBulkV2QueryJobs": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyDeliveredPlatformEvents" : {
      "Max" : 10000,
      "Remaining" : 10000
    },
    "DailyDurableGenericStreamingApiEvents": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyDurableStreamingApiEvents": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyEinsteinDataInsightsStoryCreation": {
        "Max": 1000,
        "Remaining": 1000
    },
    "DailyEinsteinDiscoveryPredictAPICalls": {
        "Max": 50000,
        "Remaining": 50000
    },
    "DailyEinsteinDiscoveryPredictionsByCDC": {
        "Max": 5000000,
        "Remaining": 5000000
    },
    "DailyEinsteinDiscoveryStoryCreation": {
        "Max": 100,
        "Remaining": 100
    },
    "DailyGenericStreamingApiEvents": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyScratchOrgs": {
        "Max": 6,
        "Remaining": 6
    },
    "DailyStandardVolumePlatformEvents": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyStreamingApiEvents": {
        "Max": 10000,
        "Remaining": 10000
    },
    "DailyWorkflowEmails": {
        "Max": 100000,
        "Remaining": 100000
    },
    "DataStorageMB": {
        "Max": 1024,
        "Remaining": 1024
    },
    "DurableStreamingApiConcurrentClients": {
        "Max": 20,
        "Remaining": 20
    },
    "FileStorageMB": {
        "Max": 1024,
        "Remaining": 1024
    },
    "HourlyAsyncReportRuns": {
        "Max": 1200,
        "Remaining": 1200
    },
    "HourlyDashboardRefreshes": {
        "Max": 200,
        "Remaining": 200
    },
    "HourlyDashboardResults": {
        "Max": 5000,
        "Remaining": 5000
    },
    "HourlyDashboardStatuses": {
        "Max": 999999999,
        "Remaining": 999999999
    },
    "HourlyLongTermIdMapping": {
        "Max": 100000,
        "Remaining": 100000
    },
    "HourlyManagedContentPublicRequests": {
        "Max": 50000,
        "Remaining": 50000
    },
    "HourlyODataCallout": {
        "Max": 20000,
        "Remaining": 20000
    },
    "HourlyPublishedPlatformEvents": {
        "Max": 50000,
        "Remaining": 50000
    },
    "HourlyPublishedStandardVolumePlatformEvents": {
        "Max": 1000,
        "Remaining": 1000
    },
    "HourlyShortTermIdMapping": {
        "Max": 100000,
        "Remaining": 100000
    },
    "HourlySyncReportRuns": {
        "Max": 500,
        "Remaining": 500
    },
    "HourlyTimeBasedWorkflow": {
        "Max": 1000,
        "Remaining": 1000
    },
    "MassEmail": {
        "Max": 5000,
        "Remaining": 5000
    },
    "MonthlyEinsteinDiscoveryStoryCreation": {
        "Max": 500,
        "Remaining": 500
    },
    "Package2VersionCreates": {
        "Max": 6,
        "Remaining": 6
    },
    "Package2VersionCreatesWithoutValidation": {
        "Max": 500,
        "Remaining": 500
    },
    "PermissionSets": {
        "Max": 1500,
        "Remaining": 1499,
        "CreateCustom": {
            "Max": 1000,
            "Remaining": 999
        }
    },
    "PrivateConnectOutboundCalloutHourlyLimitMB": {
        "Max": 0,
        "Remaining": 0
    },
    "SingleEmail": {
        "Max": 5000,
        "Remaining": 5000
    },
    "StreamingApiConcurrentClients": {
        "Max": 20,
        "Remaining": 20
    }
}

列出可用的 REST 资源

使用“按版本划分的资源”资源列出可用于 指定的 API 版本。这将提供每个附加资源的名称和 URI。例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H "Authorization: Bearer token"

示例请求正文不需要示例 JSON 响应正文

{
   "tooling" : "/services/data/v59.0/tooling",
   "metadata" : "/services/data/v59.0/metadata",
   "eclair" : "/services/data/v59.0/eclair",
   "folders" : "/services/data/v59.0/folders",
   "prechatForms" : "/services/data/v59.0/prechatForms",
   "contact-tracing" : "/services/data/v59.0/contact-tracing",
   "jsonxform" : "/services/data/v59.0/jsonxform",
   "chatter" : "/services/data/v59.0/chatter",
   "payments" : "/services/data/v59.0/payments",
   "tabs" : "/services/data/v59.0/tabs",
   "appMenu" : "/services/data/v59.0/appMenu",
   "quickActions" : "/services/data/v59.0/quickActions",
   "queryAll" : "/services/data/v59.0/queryAll",
   "commerce" : "/services/data/v59.0/commerce",
   "wave" : "/services/data/v59.0/wave",
   "iot" : "/services/data/v59.0/iot",
   "analytics" : "/services/data/v59.0/analytics",
   "search" : "/services/data/v59.0/search",
   "smartdatadiscovery" : "/services/data/v59.0/smartdatadiscovery",
   "identity" : "https://MyDomainName.my.salesforce.com/id/
      00DRO0000008aXd2AI/005RO000000HfnkYAC",
   "composite" : "/services/data/v59.0/composite",
   "parameterizedSearch" : "/services/data/v59.0/parameterizedSearch",
   "fingerprint" : "/services/data/v59.0/fingerprint",
   "theme" : "/services/data/v59.0/theme",
   "nouns" : "/services/data/v59.0/nouns",
   "domino" : "/services/data/v59.0/domino",
   "event" : "/services/data/v59.0/event",
   "serviceTemplates" : "/services/data/v59.0/serviceTemplates",
   "recent" : "/services/data/v59.0/recent",
   "connect" : "/services/data/v59.0/connect",
   "licensing" : "/services/data/v59.0/licensing",
   "limits" : "/services/data/v59.0/limits",
   "process" : "/services/data/v59.0/process",
   "dedupe" : "/services/data/v59.0/dedupe",
   "async-queries" : "/services/data/v59.0/async-queries",
   "query" : "/services/data/v59.0/query",
   "jobs" : "/services/data/v59.0/jobs",
   "localizedvalue" : "/services/data/v59.0/localizedvalue",
   "mobile" : "/services/data/v59.0/mobile",
   "emailConnect" : "/services/data/v59.0/emailConnect",
   "consent" : "/services/data/v59.0/consent",
   "tokenizer" : "/services/data/v59.0/tokenizer",
   "compactLayouts" : "/services/data/v59.0/compactLayouts",
   "sobjects" : "/services/data/v59.0/sobjects",
   "actions" : "/services/data/v59.0/actions",
   "support" : "/services/data/v59.0/support"
}

示例 XML 响应正文

<?xml version="1.0" encoding="UTF-8"?> 
<urls>
   <tooling>/services/data/v59.0/tooling</tooling>
   <metadata>/services/data/v59.0/metadata</metadata>
   <eclair>/services/data/v59.0/eclair</eclair>
   <folders>/services/data/v59.0/folders</folders>
   <prechatForms>/services/data/v59.0/prechatForms</prechatForms>
   <contact-tracing>/services/data/v59.0/contact-tracing</contact-tracing>
   <jsonxform>/services/data/v59.0/jsonxform</jsonxform>
   <chatter>/services/data/v59.0/chatter</chatter>
   <payments>/services/data/v59.0/payments</payments>
   <tabs>/services/data/v59.0/tabs</tabs>
   <appMenu>/services/data/v59.0/appMenu</appMenu>
   <quickActions>/services/data/v59.0/quickActions</quickActions>
   <queryAll>/services/data/v59.0/queryAll</queryAll>
   <commerce>/services/data/v59.0/commerce</commerce>
   <wave>/services/data/v59.0/wave</wave>
   <iot>/services/data/v59.0/iot</iot>
   <analytics>/services/data/v59.0/analytics</analytics>
   <search>/services/data/v59.0/search</search>
   <smartdatadiscovery>/services/data/v59.0/smartdatadiscovery</smartdatadiscovery>
   <identity>https://MyDomainName.my.salesforce.com/id/
      ​​​00DRO0000008aXd2BI/​005RO000000HfnkYAB</identity>
   <composite>/services/data/v59.0/composite</composite>
   <parameterizedSearch>/services/data/v59.0/parameterizedSearch</parameterizedSearch>
   <fingerprint>/services/data/v59.0/fingerprint</fingerprint>
   <theme>/services/data/v59.0/theme</theme>
   <nouns>/services/data/v59.0/nouns</nouns>
   <domino>/services/data/v59.0/domino</domino>
   <event>/services/data/v59.0/event</event>
   <serviceTemplates>/services/data/v59.0/serviceTemplates</serviceTemplates>
   <recent>/services/data/v59.0/recent</recent>
   <connect>/services/data/v59.0/connect</connect>
   <licensing>/services/data/v59.0/licensing</licensing>
   <limits>/services/data/v59.0/limits</limits>
   <process>/services/data/v59.0/process</process>
   <dedupe>/services/data/v59.0/dedupe</dedupe>
   <async-queries>/services/data/v59.0/async-queries</async-queries>
   <query>/services/data/v59.0/query</query>
   <jobs>/services/data/v59.0/jobs</jobs>
   <localizedvalue>/services/data/v59.0/localizedvalue</localizedvalue>
   <mobile>/services/data/v59.0/mobile</mobile>
   <emailConnect>/services/data/v59.0/emailConnect</emailConnect>
   <consent>/services/data/v59.0/consent</consent>
   <tokenizer>/services/data/v59.0/tokenizer</tokenizer>
   <compactLayouts>/services/data/v59.0/compactLayouts</compactLayouts>
   <sobjects>/services/data/v59.0/sobjects</sobjects>
   <actions>/services/data/v59.0/actions</actions>
   <support>/services/data/v59.0/support</support>
</urls>

更多信息

有关身份资源的信息,请参阅身份 URL。

有关其他资源,请参阅参考。

获取对象列表

使用“描述全局”资源列出组织中可用的对象以及可供登录用户使用的对象 用户。此资源还返回组织编码,以及 查询。示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/ -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{ 
  "encoding" : "UTF-8", 
  "maxBatchSize" : 200, 
  "sobjects" : [ { 
    "activateable" : false, 
    "custom" : false,
    "customSetting" : false, 
    "createable" : true, 
    "deletable" : true, 
    "deprecatedAndHidden" : false, 
    "feedEnabled" : true, 
    "keyPrefix" : "001", 
    "label" : "Account", 
    "labelPlural" : "Accounts", 
    "layoutable" : true, 
    "mergeable" : true, 
    "mruEnabled" : true, 
    "name" : "Account", 
    "queryable" : true, 
    "replicateable" : true, 
    "retrieveable" : true, 
    "searchable" : true, 
    "triggerable" : true, 
    "undeletable" : true,
    "updateable" : true, 
    "urls" : { 
      "sobject" : "/services/data/v59.0/sobjects/Account", 
      "describe" : "/services/data/v59.0/sobjects/Account/describe", 
      "rowTemplate" : "/services/data/v59.0/sobjects/Account/{ID}" 
    },
  }, 
  ...
  ]
}

如果元数据已更改,则获取对象列表

使用 Describe Global 资源和 HTTP 标头确定对象的元数据是否具有 改变。

If-Modified-Since

使用“描述全局”资源时,可以包含带有日期格式的标题。如果你这样做了, 仅当可用对象的元数据自 提供日期。如果自提供的日期以来未修改任何元数据,则返回状态代码,但无响应 身体。If-Modified-SinceEEE, dd MMM yyyy HH:mm:ss z304 Not Modified

以下示例假定在 3 月 23 日之后未对对象进行任何更改。 2015.示例:描述全局请求/services/data/v59.0/sobjects与请求一起使用的示例标头If-Modified-SinceIf-Modified-Since: Tue, 23 Mar 2015 00:00:00 GMT示例响应正文未返回响应正文示例响应状态代码

HTTP/1.1 304 Not Modified
Date: Wed, 25 Jul 2015 00:05:46 GMT

如果在 2015 年 3 月 23 日之后对对象进行了更改,则响应正文将包含 所有可用对象。有关示例,请参阅获取对象列表。

使用对象元数据

本节中的示例使用 REST API 资源来检索对象元数据 信息。有关修改或创建对象元数据信息的信息,请参阅元数据 API 开发人员 指南

  • 获取对象
    的元数据 使用 sObject 基本信息资源获取对象的元数据。
  • 获取对象
    的字段和其他元数据 使用 sObject Describe 资源检索对象的所有元数据,包括有关每个字段、URL 和子关系的信息。
  • 获取对象元数据更改
    使用 sObject Describe 资源和 HTTP 标头确定对象元数据是否已更改。If-Modified-Since

获取对象的元数据

使用 sObject 基本信息资源获取元数据 对于对象。获取帐户元数据的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H "Authorization: Bearer token"

用于获取帐户元数据的示例请求正文不需要用于获取帐户元数据的示例响应正文

{
  "objectDescribe" :
  {
    "name" : "Account",
    "updateable" : true,
    "label" : "Account",
    "keyPrefix" : "001",

    ...

    "replicateable" : true,
    "retrieveable" : true,
    "undeletable" : true,
    "triggerable" : true
  },
  "recentItems" :
  [
    {
      "attributes" :
      {
        "type" : "Account",
        "url" : "/services/data/v59.0/sobjects/Account/001D000000INjVeIAL"
      },
      "Id" : "001D000000INjVeIAL",
      "Name" : "asdasdasd"
    },

    ...

  ]
}

若要获取对象的完整描述(包括字段名称及其元数据),请参阅获取对象列表。

获取对象的字段和其他元数据

使用 sObject Describe 资源检索对象的所有元数据,包括有关每个对象的信息 字段、URL 和子关系。例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/describe/ -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
  "name" : "Account",
  "fields" :
  [
    {
      "length" : 18,
      "name" : "Id",
      "type" : "id",
      "defaultValue" : {    "value" : null  },
      "updateable" : false,
      "label" : "Account ID",
      ...
    },

    ...

  ],


  "updateable" : true,
  "label" : "Account",
  "keyPrefix" : "001",
  "custom" : false,

  ...

  "urls" :
  {
    "uiEditTemplate" : "https://MyDomainName.my.salesforce.com/{ID}/e",
    "sobject" : "/services/data/v59.0/sobjects/Account",
    "uiDetailTemplate" : "https://MyDomainName.my.salesforce.com/{ID}",
    ...
  },

  "childRelationships" :
  [
    {
      "field" : "ParentId",
      "deprecatedAndHidden" : false,
      ...
    }, 

    ....

  ],

  "createable" : true,
  "customSetting" : false,
  ...
}

有关请求正文中的项目的更多信息,请参阅《SOAP API 开发人员指南》中的 DescribesObjectResult。

获取对象元数据更改

使用 sObject Describe 资源和 HTTP 标头确定对象元数据是否已更改。

If-Modified-Since

使用 sObject Describe 资源时,可以包含带有日期格式的标题。如果这样做,则仅当对象元数据出现时,才会返回响应元数据 自提供的日期以来已更改。如果元数据自 提供的日期,状态代码 返回,不带响应正文。If-Modified-SinceEEE, dd MMM yyyy HH:mm:ss z304 Not Modified

以下示例假定没有更改,例如 new custom 字段,已在 7 月 3 日之后对Merchandise__c对象进行, 2013.示例 sObject Describe 请求

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/describe -H "Authorization: Bearer token" -H "If-Modified-Since: Wed, 3 Jul 2013 19:43:31 GMT"

示例响应正文未返回响应正文示例响应状态代码

HTTP/1.1 304 Not Modified
Date: Fri, 12 Jul 2013 05:03:24 GMT

如果在 2013 年 7 月 3 日之后对Merchandise__c进行了更改, 响应正文将包含Merchandise__c的元数据。有关示例,请参阅获取对象的字段和其他元数据。

使用记录

本节中的示例使用 REST API 资源来创建、检索、更新和 删除记录以及其他与记录相关的操作。

  • 创建记录
    使用 sObject 基本信息资源创建新记录。您可以在请求数据中提供所需的字段值,并使用 POST HTTP 方法发送请求。如果调用成功,响应正文将包含新记录的 ID。
  • 更新记录
    使用 sObject Rows 资源更新记录。在请求数据中提供更新的记录信息,并使用具有特定记录 ID 的资源的 PATCH 方法来更新该记录。单个文件中的记录必须具有相同的对象类型。
  • 删除记录
    使用 sObject Rows 资源删除记录。指定记录 ID,并使用资源的 DELETE 方法删除记录。
  • 从标准对象记录
    中获取字段值 使用 sObject Rows 资源的 GET 方法从记录中检索字段值。
  • 使用 Salesforce ID
    从外部对象记录中获取字段值 您可以使用 sObject Rows 资源从记录中检索字段值。在参数中指定要检索的字段,并使用资源的 GET 方法。fields
  • 使用外部 ID 标准字段从外部对象记录中获取字段值 使用 sObject Rows 资源从记录中检索字段
    值。在参数中指定要检索的字段,并使用资源的 GET 方法。fields
  • 使用外部 ID 获取记录 可以使用“sObject Rows by External ID”资源的 GET 方法获取具有特定外部 ID
    的记录。
  • 使用外部 ID 插入或更新(更新插入)记录 可以使用“按外部 ID 列出的 sObject 行”资源根据指定的外部 ID
    字段的值创建记录或更新现有记录(更新插入)。
  • 使用友好 URL 遍历关系 通过使用 sObject 关系资源构造友好 URL
    ,可以遍历标准对象和自定义对象中的关系字段。此方法允许您直接访问由关系关联的记录。使用友好 URL 是访问记录的更简单方法,方法是从关系字段获取对象 ID,然后检查关联的对象 ID 记录。
  • 获取给定时间范围内
    已删除记录的列表 使用 sObject Get Deleted 资源获取指定对象的已删除记录列表。指定删除给定对象的记录的日期和时间范围。已删除的记录将写入删除日志(定期清除),并将从大多数操作(如 sObject 行或查询)中筛选出来(尽管 QueryAll 将在结果中包含已删除的记录)。
  • 获取给定时间范围内
    更新的记录列表 使用 sObject Get Updated 资源获取指定对象的更新(修改或添加)记录的列表。指定更新给定对象的记录的日期和时间范围。

创建记录

使用 sObject 基本信息资源创建新记录。在 请求数据,并使用 POST HTTP 方法发送请求。响应正文 如果调用成功,则包含新记录的 ID。

以下示例请求创建一个新的客户记录,其中包含 newaccount.json 中提供的新记录。只有 name 字段是 在此示例中指定,但您也可以为其他帐户提供值 领域。创建新帐户的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H "Authorization: Bearer token" -H "Content-Type: application/json" -d "@newaccount.json"

示例请求正文 newaccount.json 文件,用于创建 新账户

{
  "Name" : "Express Logistics and Transport"
}

成功创建新帐户后的示例响应正文

{
  "id" : "001D000000IqhSLIAZ",
  "errors" : [ ],
  "success" : true
}

更新记录

使用 sObject Rows 资源更新记录。提供更新的记录 请求数据中的信息,并将资源的 PATCH 方法与 用于更新该记录的特定记录 ID。单个文件中的记录必须相同 对象类型。

在以下示例中,将更新帐户中的计费城市。更新后的 记录信息在 patchaccount.json 中提供。更新 Account 对象的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/001D000000INjVe -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @patchaccount.json -X PATCH

用于更新的示例请求正文 patchaccount.json 文件 Account 对象中的字段

{
    "BillingCity" : "San Francisco"
}

用于更新 Account 对象中的字段的示例响应正文未返回错误响应请参阅状态代码和错误响应。以下示例使用 Java 和 HttpClient 通过 REST API 更新记录。注意 HttpClient 中没有 PatchMethod,因此 PostMethod 被重写以返回 “PATCH”作为其方法名称。此示例假定资源 URL 已 传入并包含对象名称和记录 同上。

public static void patch(String url, String sid) throws IOException {
  PostMethod m = new PostMethod(url) {
    @Override public String getName() { return "PATCH"; }
  };

  m.setRequestHeader("Authorization", "OAuth " + sid);

  Map<String, Object> accUpdate = new HashMap<String, Object>();
  accUpdate.put("Name", "Patch test");
  ObjectMapper mapper = new ObjectMapper();
  m.setRequestEntity(new StringRequestEntity(mapper.writeValueAsString(accUpdate), "application/json", "UTF-8"));

  HttpClient c = new HttpClient();
  int sc = c.executeMethod(m);
  System.out.println("PATCH call returned a status code of " + sc);
  if (sc > 299) {
    // deserialize the returned error message
    List<ApiError> errors = mapper.readValue(m.getResponseBodyAsStream(), new TypeReference<List<ApiError>>() {} );
    for (ApiError e : errors)
      System.out.println(e.errorCode + " " + e.message);
  }
}

private static class ApiError {
  public String errorCode;
  public String message;
  public String [] fields;
}

如果 您使用的 HTTP 库不允许覆盖或设置任意 HTTP 方法名称,您可以发送 POST 请求并通过以下方式提供对 HTTP 方法的覆盖 查询字符串参数。在 PATCH 示例中,您可以将 PostMethod 行替换为不使用 覆盖:

_HttpMethod

PostMethod m = new PostMethod(url + "?_HttpMethod=PATCH");

删除记录

使用 sObject Rows 资源删除记录。指定记录 ID 并使用 资源来删除记录。删除客户记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/001D000000INjVe -H "Authorization: Bearer token" -X DELETE

示例请求正文不需要示例响应正文无返回

从标准对象记录中获取字段值

使用 sObject Rows 资源的 GET 方法从记录中检索字段值。

您可以使用可选参数指定要检索的字段。如果您指定的字段不存在或您无法通过 字段级安全性,则返回 400 错误响应。fields

如果不使用该参数,请求将从记录中检索所有标准字段和自定义字段。这些检索到的字段与 对象的 sObject Describe 请求返回的字段。字段级安全性无法访问的字段不会在响应正文中返回。fields

在以下示例中,从帐户中检索帐号和帐单邮政编码。从 Account 对象上的字段中检索值的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/001D000000INjVe​?fields=AccountNumber,BillingPostalCode -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
    "AccountNumber" : "CD656092",
    "BillingPostalCode" : "27215",
}

使用 Salesforce ID 从外部对象记录中获取字段值

使用 sObject Rows 资源从记录中检索字段值。指定字段 想要在参数中检索并使用 资源的 GET 方法。

fields

在以下示例中,自定义 字段是从与非高数据卷关联的外部对象中检索的 外部数据源。Country__c从 Customer 外部对象的字段中检索值的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Customer__x/x01D0000000002RIAQ?fields=Country__c -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
  "attributes" : {
    "type" : "Customer__x",
    "url" : "/services/data/v59.0/sobjects/Customer__x/x01D0000000002RIAQ"
  },
  "Country__c" : "Argentina",
  "Id" : "x01D0000000002RIAQ"
}

使用 外部 ID 标准字段

使用 sObject Rows 资源从记录中检索字段值。 在参数中指定要检索的字段,并使用资源的 GET 方法。

fields

在以下示例中,自定义 字段是从外部对象中检索的。请注意,(CACTU) 不是 Salesforce ID。相反,它是 外部对象。Country__cid从 Customer 外部对象的字段中检索值的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Customer__x/CACTU?fields=Country__c -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{
  "attributes" : {
    "type" : "Customer__x",
    "url" : "/services/data/v59.0/sobjects/Customer__x/CACTU"
  },
  "Country__c" : "Argentina",
  "ExternalId" : "CACTU"
}

使用外部 ID 获取记录

可以使用 sObject Rows by External ID 资源的 GET 方法获取具有特定外部 ID 的记录。

以下示例假定存在一个Merchandise__c自定义对象,该对象具有 MerchandiseExtID__c外部 ID 字段。使用外部 ID 检索Merchandise__c记录的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/MerchandiseExtID__c/123 -H "Authorization: Bearer token"

示例请求正文不需要示例响应正文

{ 
    "attributes" : {
        "type" : "Merchandise__c",
        "url" : "/services/data/v59.0/sobjects/Merchandise__c/a00D0000008oWP8IAM"
     },
    "Id" : "a00D0000008oWP8IAM",
    "OwnerId" : "005D0000001KyEIIA0",
    "IsDeleted" : false,
    "Name" : "Example Merchandise",
    "CreatedDate" : "2012-07-12T17:49:01.000+0000",
    "CreatedById" : "005D0000001KyEIIA0",
    "LastModifiedDate" : "2012-07-12T17:49:01.000+0000",
    "LastModifiedById" : "005D0000001KyEIIA0",
    "SystemModstamp" : "2012-07-12T17:49:01.000+0000",
    "Description__c" : "Merch with external ID",
    "Price__c" : 10.0,
    "Total_Inventory__c" : 100.0,
    "Distributor__c" : null,
    "MerchandiseExtID__c" : 123.0
}

使用外部 ID 插入或更新(更新插入)记录

可以使用“按外部 ID 列出的 sObject 行”资源执行以下操作: 根据指定值创建记录或更新现有记录 (upsert) 外部 ID 字段。

重要

在可能的情况下,我们更改了非包容性条款,以符合我们的 平等的公司价值观。我们保留了某些条款,以避免对 客户实施。

  • 如果外部 ID 不匹配,则根据 请求正文。
  • 如果外部 ID 匹配一次,则记录将根据 请求正文。
  • 如果外部 ID 多次匹配,则会报告 300 错误,并且 未创建或更新记录。

以下各节介绍如何使用外部 ID 资源进行检索 按外部 ID 和更新插入记录进行记录。

注意

在 REST API 中,更新插入使用外部 ID,而不是记录 ID。然而,在 Apex 中,upsert 可以是 与外部 ID 和记录 ID 一起使用。请注意两者的区别 REST API 和 Apex。

更新插入新记录

此示例使用 PATCH 方法插入新记录。它假设 外部 ID 字段“customExtIdField__c”已添加到帐户中。 它还假定 customExtIdField 值为 11999 的客户记录 尚不存在。更新插入尚不存在的记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/customExtIdField__c/11999 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @newrecord.json -X PATCH

示例 JSON 请求正文 newrecord.json 文件

{
    "Name" : "California Wheat Corporation",
    "Type" : "New Customer"
}

示例 JSON 响应成功的响应 是:

{
    "id" : "00190000001pPvHAAU",
    "errors" : [ ],
    "success" : true,
    "created": true
}

这 HTTP 状态代码为 201(已创建)。

注意

参数存在 在 API 版本 46.0 及更高版本的响应中。它不会出现在 早期版本。created错误响应外部 ID 不正确 田:

{
    "message" : "The requested resource does not exist",
    "errorCode" : "NOT_FOUND"
}

有关详细信息,请参阅状态代码和错误响应。

使用 id 作为外部插入新记录 编号

此示例使用 POST 方法作为特殊情况插入一条记录,其中 Id 字段被视为外部 ID。因为价值 的 Id 是 ,它是 从请求中省略。在编写要更新插入的代码时,此模式非常有用 使用不同外部 ID 的多个记录,并且您不想请求单独的 ID 资源。使用 Id 的 POST 在 API 版本 37.0 中可用,并且 后。null插入尚不存在的记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/Id -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @newrecord.json -X POST

示例 JSON 请求正文 newrecord.json 文件

{
    "Name" : "California Wheat Corporation",
    "Type" : "New Customer"
}

示例 JSON 响应成功的响应 是:

{
    "id" : "001D000000Kv3g5IAB",
    "success" : true,
    "errors" : [ ],
    "created": true
}

这 HTTP 状态代码为 201(已创建)。

注意

参数存在 在 API 版本 46.0 及更高版本的响应中。它不会出现在 早期版本。created

更新插入现有记录

此示例使用 PATCH 方法更新现有记录。它假设 外部 ID 字段“customExtIdField__c”已添加到帐户中 并且存在 customExtIdField 值为 11999 的客户记录。请求 使用 updates.json 指定更新的字段值。更新插入现有记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/customExtIdField__c/11999 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @updates.json -X PATCH

示例 JSON 请求正文 updates.json 文件

{
    "BillingCity" : "San Francisco"
}

示例 JSON 响应在 API 版本 46.0 及更高版本中,HTTP 状态代码为 200 (OK) 和 成功响应 是:

{
    "id" : "001D000000Kv3g5IAB",
    "success" : true,
    "errors" : [ ],
    "created": false
}

在 API 版本 45.0 及更早版本,HTTP 状态代码为 204(无内容) 并且没有响应机构。错误响应如果外部 ID 值不唯一,则返回 HTTP 状态代码 300。 加上与查询匹配的记录列表。更多信息 有关错误,请参阅状态代码和错误响应。如果外部 ID 字段不存在,则会显示错误消息和代码 返回:

{
    "message" : "The requested resource does not exist",
    "errorCode" : "NOT_FOUND"
}

更新插入记录并与外部 ID 关联

如果某个对象使用关系引用另一个对象,则可以 使用 REST API 插入或更新记录,并使用 外部 ID。以下示例创建一条记录,并通过以下方式将其与父记录关联 外部 ID。它假设以下几点:

  • Merchandise__c具有名为 MerchandiseExtID__c。
  • Line_Item__c具有名为 LineItemExtID__c,以及与Merchandise__c的关系。
  • Merchandise__c存在MerchandiseExtID__c值为 123.
  • LineItemExtID__c值为 456 的Line_Item__c记录不存在。这是创建并关联到 Merchandise__c记录。

更新插入记录和引用相关对象的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Line_Item__c/LineItemExtID__c/456 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @new.json -X PATCH

示例 JSON 请求正文 new.json 文件请注意,相关的Merchandise__c记录是使用 Merchandise__c的外部 ID 田。

{
   "Name" : "LineItemCreatedViaExtID",
   "Merchandise__r" :
   {
       "MerchandiseExtID__c" : 123
   }
}

示例 JSON 响应成功的响应 是:

{
    "id" : "a02D0000006YUHrIAO",
    "errors" : [ ],
    "success" : true,
    "created": true
}

HTTP 状态代码为 201(已创建)。

注意

参数存在 在 API 版本 46.0 及更高版本的响应中。它不会出现在 早期版本。created错误响应如果外部 ID 值不唯一,则返回 HTTP 状态代码 300。 加上与查询匹配的记录列表。更多信息 有关错误,请参阅状态代码和错误响应。如果外部 ID 字段不存在,则会显示错误消息和代码 返回:

{
    "message" : "The requested resource does not exist",
    "errorCode" : "NOT_FOUND"
}

您还可以使用此方法更新现有记录。例如,如果你 创建了上面示例中所示的Line_Item__c,您可以尝试更新 相关Merchandise__c使用另一个请求。更新记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Line_Item__c/LineItemExtID__c/456 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @updates.json -X PATCH

示例 JSON 请求正文 updates.json 文件这假设存在另一个Merchandise__c记录,并且 MerchandiseExtID__c值 333.

{
   "Merchandise__r" :
   {
       "MerchandiseExtID__c" : 333
   }
}

示例 JSON 响应在 API 版本 46.0 及更高版本中,HTTP 状态代码为 200 (OK) 和 成功响应 是:

{
    "id" : "001D000000Kv3g5IAB",
    "success" : true,
    "errors" : [ ],
    "created": false
}

在 API 版本 45.0 及更早版本,HTTP 状态代码为 204(否 内容),并且没有响应正文。如果关系类型为主从,并且关系设置为不 允许重新设置父级,并且您尝试更新父级外部 ID,您将收到一个 HTTP 状态代码 400 错误,错误代码为 INVALID_FIELD_FOR_INSERT_UPDATE。

另见

  • 按外部 ID 划分的 sObject 行

使用友好 URL 遍历关系

您可以通过构造 使用 sObject 关系资源的友好 URL。这种方法允许您直接 访问由关系关联的记录。使用友好 URL 是 通过从关系字段获取对象 ID,然后检查 关联的对象 ID 记录。

重要

在可能的情况下,我们更改了非包容性条款,以符合我们的 平等的公司价值观。我们保留了某些条款,以避免对客户产生任何影响 实现。

关系名称遵循某些约定,这些约定取决于方向 (parent to 子项,或子项到父项)的关系和相关对象的名称。这 约定在了解关系名称中进行了介绍。 SOQL 和 SOSL 参考。在单个 REST 中可以进行的关系遍历次数是有限制的 API 调用。这些限制与 SOQL 的限制相同,如了解关系查询中所述 SOQL 和 SOSL 参考中的限制。保留以下内容 遍历关系时要牢记局限性。

  • 指定子级与父级关系时,不能超过五个级别 走过。以下内容遍历了两个子项到父项 关系。https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/ChildOfChild__c/record id/Child__r/ParentOfChild__r
  • 指定父子关系时,不能超过一个级别 走过。以下内容遍历一个父到子 关系。https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/ParentOfChild__c/record id/Child__r

遍历标准对象

标准对象“联系人”包含“客户”标准的关系字段 对象。以下示例检索与联系人相关的客户记录 记录。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Contact/0035e00000PiemmAAB/Account -H "Authorization: Bearer token"

用于遍历标准对象关系的示例请求正文不需要用于遍历标准对象的示例响应正文 simple 关系

{
    "attributes": {
        "type": "Account",
        "url": "/services/data/v59.0/sobjects/Account/0015e00000TwULCAA3"
    },
    "Id": "0015e00000TwULCAA3",
    "IsDeleted": false,
    "Name": "relationshipAccountName",
    "PhotoUrl": "/services/images/photo/0015e00000TwULCAA3",
    "OwnerId": "0055e000003E8ooAAC",
    "CreatedDate": "2021-11-06T17:38:40.000+0000",
    "CreatedById": "0055e000003E8ooAAC",
    "LastModifiedDate": "2021-11-06T17:38:40.000+0000",
    "LastModifiedById": "0055e000003E8ooAAC",
    "SystemModstamp": "2021-11-06T17:38:40.000+0000",
    "LastActivityDate": null,
    "LastViewedDate": "2021-11-06T17:40:50.000+0000",
    "LastReferencedDate": "2021-11-06T17:40:50.000+0000"
}

遍历简单关系的示例此名为 Merchandise__c 的自定义对象包含一个查找关系字段,用于 自定义对象Distributor__c子对象。以下示例检索 Distributor__c与Merchandise__c记录相关的记录。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token"

用于遍历简单关系的示例请求正文不需要用于遍历简单关系的示例响应正文

{
    "attributes" : 
    { 
        "type" : "Distributor__c",
        "url" : "/services/data/v59.0/sobjects/Distributor__c/a03D0000003DUhcIAG"
    },
    "Id" : "a03D0000003DUhcIAG",
    "OwnerId" : "005D0000001KyEIIA0",
    "IsDeleted" : false,
    "Name" : "Distributor1",
    "CreatedDate" : "2011-12-16T17:43:01.000+0000",
    "CreatedById" : "005D0000001KyEIIA0",
    "LastModifiedDate" : "2011-12-16T17:43:01.000+0000",
    "LastModifiedById" : "005D0000001KyEIIA0",
    "SystemModstamp" : "2011-12-16T17:43:01.000+0000",
    "Location__c" : "San Francisco"
}

如果没有相关记录与关系名称关联,则 REST API 调用将失败。 因为关系是无法遍历的。使用前面的示例,如果 Distributor__c Merchandise__c 记录中的字段设置为 ,则 GET 调用将返回 404 错误响应。null您可以在 单个 REST API 调用,只要不超过关系查询限制即可。如果 自定义对象Line_Item__c是与Merchandise__c自定义项关系中的子对象 对象,并且Merchandise__c还有一个子对象Distributor__c自定义对象,您可以访问 Distributor__c记录从Line_Item__c记录开始,使用类似 以后。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Line_Item__c/a02D0000006YL7XIAW/Merchandise__r/Distributor__r -H "Authorization: Bearer token"

关系遍历还支持以下关系的 PATCH 和 DELETE 方法: 解析为单个记录。使用 PATCH 方法,您可以更新相关的 记录。使用 PATCH 更新关系记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token"  -d @update_info.json -X PATCH

用于更新 update_info.json 中包含的关系记录的示例 JSON 请求正文

{
    "Location__c" : "New York"
}

用于更新关系记录的示例响应正文未返回

最后,使用 DELETE 方法可以删除相关记录。使用 DELETE 删除关系记录的示例

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token" -X DELETE

删除关系记录的请求正文示例不需要更新关系记录的示例响应正文未返回

遍历具有多个记录的关系

您可以遍历与多个记录的关系,并获得以下响应: 包含记录集。对于解析为多个记录的关系, 仅支持 GET 方法。遍历具有多条记录的关系的示例如果我们有一个名为 Merchandise__c 的自定义对象,其中包含 master – Line_Item__c自定义对象的详细信息关系字段, 以下示例Line_Item__c检索与 Merchandise__c记录。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Line_Items__r -H "Authorization: Bearer token"

用于遍历具有多个关系的示例请求正文 记录不需要用于遍历具有多个关系的示例响应正文 记录在此示例中,有两条Line_Item__c记录是 检索。

{
    "done" : true,
    "totalSize" : 2,
    "records" :
    [
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v59.0/sobjects/Line_Item__c/a02D0000006YL7XIAW"
            },
            "Id" : "a02D0000006YL7XIAW",
            "IsDeleted" : false,
            "Name" : "LineItem1",
            "CreatedDate" : "2011-12-16T17:44:07.000+0000",
            "CreatedById" : "005D0000001KyEIIA0",
            "LastModifiedDate" : "2011-12-16T17:44:07.000+0000",
            "LastModifiedById" : "005D0000001KyEIIA0",
            "SystemModstamp" : "2011-12-16T17:44:07.000+0000",
            "Unit_Price__c" : 9.75,
            "Units_Sold__c" : 10.0,
            "Merchandise__c" : "a00D0000008oLnXIAU",
            "Invoice_Statement__c" : "a01D000000D85hkIAB"
        },
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v59.0/sobjects/Line_Item__c/a02D0000006YL7YIAW"
            },
            "Id" : "a02D0000006YL7YIAW",
            "IsDeleted" : false,
            "Name" : "LineItem2",
            "CreatedDate" : "2011-12-16T18:53:59.000+0000",
            "CreatedById" : "005D0000001KyEIIA0",
            "LastModifiedDate" : "2011-12-16T18:53:59.000+0000",
            "LastModifiedById" : "005D0000001KyEIIA0",
            "SystemModstamp" : "2011-12-16T18:54:00.000+0000",
            "Unit_Price__c" : 8.5,
            "Units_Sold__c" : 8.0,
            "Merchandise__c" : "a00D0000008oLnXIAU",
            "Invoice_Statement__c" : "a01D000000D85hkIAB"
        }
    ]
}

这 结果数据的序列化结构与结果数据的格式相同 通过 REST API 执行 SOQL 查询。有关通过以下方式执行 SOQL 查询的更多详细信息,请参阅查询 REST API

如果没有相关记录与关系名称关联,则 REST API 调用 返回 200 响应,响应正文中没有记录数据。这个结果是 与遍历到单个记录的空关系时的结果形成对比, 返回 404 错误响应。此行为是因为单个记录大小写 解析为可与 PATCH 或 DELETE 方法一起使用的 REST 资源。在 相比之下,只能查询多记录大小写。如果对具有多个记录的关系的初始 GET 请求仅返回部分 的结果中,响应的末尾包含字段 。例如,您可以获取一个字段 就像下面这样在你的末尾 响应。

nextRecordsUrl

"nextRecordsUrl" : "/services/data/v59.0/query/01gD0000002HU6KIAW-2000"

您可以使用实例提供的 URL 请求下一批记录 和会话信息,然后重复,直到检索到所有记录。这些 请求使用和不使用 包括任何参数。最后一批记录没有字段。nextRecordsUrlnextRecordsUrl检索剩余结果的示例用法

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query/01gD0000002HU6KIAW-2000 -H "Authorization: Bearer token"

用于检索其余结果的示例请求正文不需要用于检索剩余结果的示例响应正文

{
    "done" : true,
    "totalSize" : 3200,
    "records" : [...]
}

筛选结果字段

通过关系遍历检索记录时,可以选择仅指定 使用参数返回记录字段的子集。多个字段用逗号分隔。这 以下示例仅从Distributor__c中检索 Location__c 字段 与Merchandise__c关联的记录 记录:

fields

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r?fields=Location__c -H "Authorization: Bearer token"

这 JSON 响应数据类似于 以后:

{
    "attributes" :
    {
        "type" : "Distributor__c",
        "url" : "/services/data/v59.0/sobjects/Distributor__c/a03D0000003DUhhIAG"
    },
    "Location__c" : "Chicago",
}

同样,对于产生多条记录的请求,您可以使用字段列表 指定记录集中返回的字段。例如,假设您有一个 与两个Line_Item__c记录关联的关系。你只想要 这些记录中的名称和Units_Sold__c字段。您可以使用以下命令 叫。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/a01D000000INjVe/Line_Items__r?fields=Name,Units_Sold__c -H "Authorization: Bearer token"

这 响应数据将类似于 以后。

{
    "done" : true,
    "totalSize" : 2,
    "records" : 
    [
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v59.0/sobjects/Line_Item__c/a02D0000006YL7XIAW"
            },
            "Name" : "LineItem1",
            "Units_Sold__c" : 10.0
        },
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v59.0/sobjects/Line_Item__c/a02D0000006YL7YIAW"
            },
            "Name" : "LineItem2",
            "Units_Sold__c" : 8.0
        }
    ]
}

如果字段参数集中列出的任何字段对活动对象不可见 用户,则 REST API 调用失败。在前面的示例中,如果 Units_Sold_c 字段 被字段级安全性对活动用户隐藏,则调用将返回 400 错误响应。

获取给定时间范围内已删除记录的列表

使用 sObject Get Deleted 资源获取指定对象的已删除记录列表。指定日期和时间范围 其中删除了给定对象的记录。已删除的记录将写入删除日志(定期清除),并将从大多数操作中筛选出,例如 sObject 行或查询(尽管 QueryAll 将在结果中包含已删除的记录)。获取已删除的Merchandise__c记录列表的示例用法 2013年5月5日至2013年5月10日

curl https://MyDomainName.my/services/data/v59.0/sobjects/Merchandise__c/deleted/​​​?start=2013-05-05T00%3A00%3A00%2B00%3A00&end=2013-05-10T00%3A00%3A00%2B00%3A00 -H "Authorization: Bearer token"

示例请求正文不需要JSON 示例响应正文

{ 
    "deletedRecords" : 
    [ 
        { 
            "id" : "a00D0000008pQRAIA2", 
            "deletedDate" : "2013-05-07T22:07:19.000+0000"
        }
    ],
    "earliestDateAvailable" : "2013-05-03T15:57:00.000+0000",
    "latestDateCovered" : "2013-05-08T21:20:00.000+0000"
}

XML 示例响应正文

<?xml version="1.0" encoding="UTF-8"?> 
<Merchandise__c> 
    <deletedRecords> 
        <deletedDate>2013-05-07T22:07:19.000Z</deletedDate> 
        <id>a00D0000008pQRAIA2</id> 
    </deletedRecords>
    <earliestDateAvailable>2013-05-03T15:57:00.000Z</earliestDateAvailable>
    <latestDateCovered>2013-05-08T21:20:00.000Z</latestDateCovered>
</Merchandise__c>

获取给定时间范围内更新的记录列表

使用 sObject Get Updated 资源获取 指定的对象。指定给定记录的日期和时间范围 对象已更新。获取已更新的Merchandise__c记录列表的示例用法 2013年5月6日至2013年5月10日

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Merchandise__c/updated/​​​?start=2013-05-06T00%3A00%3A00%2B00%3A00&end=2013-05-10T00%3A00%3A00%2B00%3A00 -H "Authorization: Bearer token"

示例请求正文不需要JSON 示例响应正文

{ 
    "ids" : 
    [ 
        "a00D0000008pQR5IAM", 
        "a00D0000008pQRGIA2", 
        "a00D0000008pQRFIA2"
    ],
    "latestDateCovered" : "2013-05-08T21:20:00.000+0000" 
}

XML 示例响应正文

<?xml version="1.0" encoding="UTF-8"?> 
<Merchandise__c> 
    <ids>a00D0000008pQR5IAM</ids>
    <ids>a00D0000008pQRGIA2</ids>
    <ids>a00D0000008pQRFIA2</ids>
    <latestDateCovered>2013-05-08T21:20:00.000Z</latestDateCovered>
</Merchandise__c>

REST快开始

若要设置和运行 REST API,请将一些基本请求发送到 Salesforce的。本快速入门介绍了如何设置基本环境和更新记录 使用 REST API。您可以通过多种方式设置和使用 REST API,示例演示了如何使用 免费的 Developer Edition 和 cURL。

  1. 使用 cURL 了解可与 cURL
    一起使用以向 Salesforce 发出请求的格式。此 Quick Start 使用 cURL 示例,但您可以使用任何可以发出 REST 请求的工具或开发环境。
  2. 第一步:注册 Salesforce Developer Edition Developer Edition
    提供了一个免费且简单的解决方案,以便您可以使用 Salesforce 进行测试和开发。
  3. 第二步:设置身份验证
    若要成功发送请求,REST API 需要通过身份验证获取的访问令牌。虽然您可以针对自己的连接应用程序创建和进行身份验证,但为了方便起见,这些快速入门示例使用 Salesforce CLI。Salesforce CLI 是一个可以进行身份验证的连接应用程序,无需进行任何配置。
  4. 第三步:演练示例代码
    要访问 Salesforce 中不同类型的资源,请发出一系列 REST 请求。在尝试这些示例之前,请确保完成先决条件并获取本快速入门的步骤 1 中的访问令牌。
  5. 使用其他工具 其他工具
    可用于从 Salesforce 组织获取数据。

使用 cURL

了解可用于 cURL 向 Salesforce 发出请求的格式。 此 Quick Start 使用 cURL 示例,但您可以使用任何工具或开发环境 可以发出 REST 请求。

充分熟悉 cURL,以便能够理解本指南中的示例 并将它们翻译成您正在使用的工具。附加包含 请求中,您必须正确设置访问令牌的格式。使用这些提示来帮助您使用 cURL 在完成快速入门时。有关 cURL 的详细信息,请参阅 curl.se。

附加请求正文

许多示例包括请求正文,即包含请求数据的 JSON 或 XML 文件。 使用 cURL 时,请将这些文件保存到本地系统,并使用 或选项。—data-binary-d此示例附加文件。

new-account.json

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H 'Authorization Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" —d @new-account.json -X POST

处理访问令牌中的感叹号运行 cURL 示例时,您可能会在 macOS 和 Linux 系统上出现错误,因为 OAuth 访问令牌中存在感叹号 (!)。为避免出现此错误, 对感叹号进行转义或使用单引号。转义感叹号 访问令牌,当访问令牌用双括起来时,在其前面插入反斜杠 引号。

\!

例如,访问令牌字符串 此 cURL 命令的感叹号 (!) 已转义。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H "Authorization: Bearer 00DE0X0A0M0PeLE\!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE"

或 您可以将访问令牌括在单引号内,以免对感叹号进行转义。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE'

重要

所有引号,无论是单引号还是双引号,都必须是直引号,而不是 卷曲引号。

步 一:注册 Salesforce Developer Edition

Developer Edition 提供了一个免费且简单的解决方案,以便您可以将 Salesforce 用于 测试和开发。要注册 Developer Edition 帐户,请转到 developer.salesforce.com/signup。

注意

开发商 版本数据存储最大为 5 MB。此限制不会阻止您使用这些 例子。

如果您有开发沙盒,则可以将其与这些示例一起使用。

在开始之前,请按照以下方式验证您的用户配置文件是否具有 API 已启用权限 Salesforce 帮助中的用户权限中的说明。

第二步:设置身份验证

若要成功发送请求,REST API 需要由 认证。尽管您可以针对自己的连接应用创建和进行身份验证, 为方便起见,这些快速入门示例使用 Salesforce CLI。Salesforce CLI 是连接的 可以进行身份验证的应用程序,并且无需进行任何操作即可进行配置。

使用 Salesforce CLI 获取访问令牌

使用您从 Salesforce CLI 获取的访问令牌(也称为“持有者令牌”) 对 cURL 请求进行身份验证。

  1. 安装或更新 Salesforce CLI。.
    1. 如果您已安装 Salesforce CLI,请按照更新 Salesforce CLI 中的说明进行更新。
    2. 如果您需要安装 Salesforce CLI, 为您的操作系统安装最新版本。
    3. 验证您的安装。
  2. 使用 Salesforce CLI 登录您的开发人员组织。sf org login web浏览器打开 https://login.salesforce.com。
  3. 在浏览器中,使用用户的凭据登录到开发人员组织。
  4. 在浏览器中,单击允许”以允许访问。在命令下 行中,您会看到类似的确认 消息。Successfully authorized juliet.capulet@empathetic-wolf-g5qddtr.com with org ID 00D5fORGIDEXAMPLE
  5. 在命令行中,通过查看有关以下内容的身份验证信息来获取访问令牌 您的组织。sf org display --target-org <username>为 例:sf org display --target-org juliet.capulet@empathetic-wolf-g5qddtr.com例 命令输出:=== Org Description KEY VALUE ─────────────── ──────────────────────────────────────────────────────────────────────────────────────────────────────────────── Access Token 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE Api Version 59.0 Client Id PlatformCLI Created By jules@sf.com Created Date 2023-11-16T20:35:21.000+0000 Dev Hub Id jules@sf.com Edition Developer Expiration Date 2023-11-23 Id 00D5fORGIDEXAMPLE Instance Url https://MyDomainName.my.salesforce.com Org Name Dreamhouse Signup Username juliet.capulet@empathetic-wolf-g5qddtr.com Status Active Username juliet.capulet@empathetic-wolf-g5qddtr.com在 ,记下长访问令牌字符串和实例 URL 字符串。您需要两者才能发出 cURL 请求。注意在访问后获取新令牌 令牌过期时,请重复此步骤以查看您的身份验证信息。

可选的 Salesforce CLI 快捷方式

成功进行身份验证后,请在 cURL 中尝试这些可选快捷方式 工作流,以简化未来使用 Salesforce CLI 进行身份验证的流程。

列出我的组织

sf org list

列出您创建的所有组织 或经过身份验证。

打开我的组织

sf org open --target-org <username>

打开 浏览器中的指定组织(由用户名或别名标识)。因为你已经成功了 以前使用 Salesforce CLI 命令向此组织进行身份验证,不需要提供您的凭据 再。

org login web

显示“我的组织”的访问令牌

sf org display --target-org <username>

输出 包括您的访问令牌、客户端 ID、连接状态、组织 ID、实例 URL、用户名和 别名(如果适用)。

为我的用户名设置别名为方便起见,请为您的用户名创建一个别名,这样您就不必输入 整个 Salesforce 字符串。例如,代替

juliet.capulet@empathetic-wolf-g5qddtr.com

创造 像

dev

要在此示例中设置别名, 跑

sf alias set dev juliet.capulet@empathetic-wolf-g5qddtr.com

在脚本中使用这些命令

通过调用标志来使用 CLI 的 JSON 输出。 请求 JSON 输出提供一致的输出格式,非常适合运行 脚本。如果没有该标志,CLI 可以更改 输出格式。–json–json

第三步:演练示例代码

要访问 Salesforce 中不同类型的资源,请发出一系列 REST 请求。 在尝试这些示例之前,请确保完成先决条件并获取访问权限 令牌。

您可以复制并粘贴这些示例,以使用 cURL 发送它们。但首先将基本 URI 替换为您的 Salesforce 域。为 有关 REST 请求剖析的信息,请参阅 REST 资源和请求。MyDomainName

获取 Salesforce 版本

要检索有关每个可用 Salesforce 版本的信息,请提交版本请求。在这种情况下,请求不需要身份验证。

curl https://MyDomainName.my.salesforce.com/services/data/

此请求的输出(包括响应标头)指定所有有效的 版本。结果可以包含多个值。

Content-Length: 88 
Content-Type: application/json; 
charset=UTF-8 Server:
[
    {
        "label":"Spring '11",
        "url":"/services/data/v21.0",
        "version":"21.0"
    }
    ...
]

获取资源列表

检索可用于 Salesforce 的资源列表,在此示例中,用于 版本 59.0,请提交“按版本划分的资源”请求。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H "Authorization: Bearer access_token"

此请求的输出显示这是 Salesforce 版本 59.0 中的可用资源之一。sobjects

{
    "sobjects" : "/services/data/v59.0/sobjects",
    "search" : "/services/data/v59.0/search",
    "query" : "/services/data/v59.0/query",
    "recent" : "/services/data/v59.0/recent"
}

获取可用列表 对象

要请求可用对象的列表,请提交“描述全局”请求。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/ -H "Authorization: Bearer access_token"

此请求的输出显示 Account 对象可用。

Transfer-Encoding: chunked 
Content-Type: application/json; 
charset=UTF-8 Server:
{
 "encoding" : "UTF-8",
 "maxBatchSize" : 200,
 "sobjects" : [ {
    "name" : "Account",
    "label" : "Account",
    "custom" : false,
    "keyPrefix" : "001",
    "updateable" : true,
    "searchable" : true,
    "labelPlural" : "Accounts",
    "layoutable" : true,
    "activateable" : false,
    "urls" : { "sobject" : "/services/data/v59.0/sobjects/Account",
    "describe" : "/services/data/v59.0/sobjects/Account/describe",
    "rowTemplate" : "/services/data/v59.0/sobjects/Account/{ID}" },
    "createable" : true,
    "customSetting" : false,
    "deletable" : true,
    "deprecatedAndHidden" : false,
    "feedEnabled" : false,
    "mergeable" : true,
    "queryable" : true,
    "replicateable" : true,
    "retrieveable" : true,
    "undeletable" : true,
    "triggerable" : true },
   },
...

获取对象基本信息

若要检索有关可用 Account 对象元数据的基本信息,请提交 sObject 基本信息请求。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H "Authorization: Bearer access_token"

此请求的输出显示 Account 对象的基本属性,例如其 名称和标签,并列出最近使用的帐户。

{
    "objectDescribe" : 
    {  
        "name" : "Account",  
        "updateable" : true,  
        "label" : "Account",  
        "keyPrefix" : "001",  
        
        ...
        
        "replicateable" : true,  
        "retrieveable" : true,  
        "undeletable" : true,  
        "triggerable" : true
    },
    "recentItems" : 
    [ 
        {  
            "attributes" : 
            {    
                "type" : "Account",    
                "url" : "/services/data/v59.0/sobjects/Account/001D000000INjVeIAL"  
            },  
            "Id" : "001D000000INjVeIAL",  
            "Name" : "asdasdasd"
        }, 

        ...

    ]
}

获取字段列表

若要检索更详细的信息,请提交 sObject Describe 请求。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/describe/ -H "Authorization: Bearer access_token"

此请求的输出显示有关帐户的更多详细信息 对象,例如其字段属性和子关系。

{
    "name" : "Account",
    "fields" : 
    [
        {
            "length" : 18,
            "name" : "Id",
            "type" : "id",
            "defaultValue" : { "value" : null },
            "updateable" : false,
            "label" : "Account ID",
            ...
        },
        ...
    ],
    "updateable" : true,
    "label" : "Account",
    ...
    "urls" : 
    {  
        "uiEditTemplate" : "https://MyDomainName.my.salesforce.com/{ID}/e",  
        "sobject" : "/services/data/v59.0/sobjects/Account",  
        "uiDetailTemplate" : "https://MyDomainName.my.salesforce.com/{ID}",  
        "describe" : "/services/data/v59.0/sobjects/Account/describe",  
        "rowTemplate" : "/services/data/v59.0/sobjects/Account/{ID}",  
        "uiNewRecord" : "https://MyDomainName.my.salesforce.com/001/e"
    },
    "childRelationships" : 
    [ 
        {  
            "field" : "ParentId",  
            "deprecatedAndHidden" : false,  
            ...
        }, 
        ...
    ],
     
    "createable" : true,
    "customSetting" : false,
    ...
}

执行 SOQL 查询

若要执行检索所有帐户名称值列表的 SOQL 查询,请提交 查询请求。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/query?q=SELECT+name+from+Account -H "Authorization: Bearer access_token"

输出列出了可用的帐户名称,以及每个名称的前面属性 包括帐户 ID。

{
    "done" : true,
    "totalSize" : 14,
    "records" :
    [
        {
            "attributes" :
            {
                "type" : "Account",
                "url" : "/services/data/v59.0/sobjects/Account/001D000000IRFmaIAH"
            },
            "Name" : "Test 1"
        },
        {
            "attributes" :
            {
                "type" : "Account",
                "url" : "/services/data/v59.0/sobjects/Account/001D000000IomazIAB"
            },
            "Name" : "Test 2"
        },
        ...
    ]
}

注意

您可以在 Salesforce SOQL 和 SOSL 参考中找到有关 SOQL 的更多信息 指南。

更新记录中的字段

若要检索其中一个帐户并更新其帐单城市,请提交 sObject 行请求。要更新对象,请创建一个名为 patchaccount.json 的文本文件,其中包含新的计费城市 信息。

{
    "BillingCity" : "Fremont"
}

在 REST 请求中指定此 JSON 文件。cURL 表示法在指定数据时需要该选项。查看更多 信息,请参阅 http://curl.haxx.se/docs/manpage.html。—d

此外,指定方法,该方法用于 更新 REST 资源。此 cURL 命令检索指定的 Account 对象 使用其 ID 字段并更新其帐单城市。PATCH

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/001D000000IroHJ -H "Authorization: Bearer access_token" -H "Content-Type: application/json" --data-binary @patchaccount.json -X PATCH

不返回响应正文,只返回标头。

HTTP/1.1 204 No Content
Server: 
Content-Length: 0

若要查看帐单地址是否已更改为 Fremont,请刷新 帐户。

使用其他工具

其他工具可用于从 Salesforce 组织获取数据。

如果不想使用 CURL,可以使用其他工具来练习 API。可能 选项包括:

  • Salesforce 命令行界面。
  • Postman(第三方工具)。有关详细信息,请参阅 Postman API 客户端 Trailhead 模块。

这些工具提供了简化创建和发送过程的功能 许多 API 请求。

REST API 简介

REST API 允许您以编程方式访问 Salesforce 中的数据。这 REST API 的灵活性和可扩展性使其成为集成 Salesforce 的绝佳选择 到您的应用程序中,并用于大规模执行复杂的操作。

使用本指南设置部署环境并了解有关以下方面的高级详细信息 数据访问。但是,理解和使用 REST API 需要对软件有基本的了解 开发、Web 服务和 Salesforce 用户界面。

如果您想立即采取行动,快速入门指南涵盖了帮助您入门的基础知识 和运行。

如果您正在寻找有关 Salesforce API 的更多上下文,请查看链接列表。

提示

Salesforce REST API 旨在与 Salesforce 对象一起使用。请参阅 Salesforce 的对象参考 有关 Salesforce 对象的介绍和更多信息的平台。

关于 REST API

REST API 是可用于访问 Salesforce 的多个 Web 界面之一 数据,而不使用 Salesforce 用户界面。通过 API 访问,您可以执行操作和 根据需要将 Salesforce 集成到您的应用程序中。

您可以使用 REST API 工具通过发送 HTTP 在 Salesforce 中创建、操作和搜索数据 对 Salesforce 中端点的请求。根据您发送请求的位置,您可以访问和操作 在不同的信息上,称为资源。资源包括记录、查询结果、 元数据等。

REST API 使用 RESTful 架构来提供简单且一致的接口。一个 REST API 的主要优点是它不需要太多工具即可访问您的数据。它 比 SOAP API 更易于使用,但仍然提供了大量功能。

尽管 REST API 非常适合访问和查询记录,但其他 Salesforce API,例如 Bulk 2.0 API、元数据 API 和 Connect REST API 为特定 任务。

REST API 发行说明

使用 Salesforce 发行说明了解 REST API。

有关影响 Salesforce Platform(包括 REST API)的更新和更改,请参阅 API 发行说明。

为 新的、已更改的和已弃用的调用以及特定于 REST API 的其他更改,请参阅 Salesforce 发行说明中的 REST API。

支持的版本和所需的权限

要使用 Salesforce API 访问您的 Salesforce 组织和数据,您需要一个组织 以及启用了 API 访问权限的用户。有多个支持 API 的 Salesforce 版本 访问权限和向用户授予 API 权限的多种方式。

API 访问支持的版本

默认情况下,API 访问在 Enterprise、Performance、Unlimited 和 Developer 中处于启用状态 版本组织。Professional Edition 组织可以将 API 访问权限添加为附加组件。查看更多 信息,请访问 Salesforce 帮助:使用“您的”添加产品和许可证 帐户应用程序或联系 Salesforce 客户经理。

如果您向没有 API 访问权限的组织发送 API 请求,Salesforce 将返回错误。API_DISABLED_FOR_ORG

为了保护生产组织中的配置和实时数据,我们建议使用 用于主动开发和测试的隔离环境,例如 aDeveloper Edition org、 沙盒或 Scratch 组织。准备就绪后,您可以将成功的更改转移到生产中 组织。

API 用户权限

若要进行任何 API 调用,用户必须在用户中启用“已启用 API”权限 他们分配的配置文件。默认情况下,某些配置文件上启用此权限,包括 Developer Edition 组织中提供的许多配置文件。在受支持的版本中,您还可以使用 Salesforce 集成用户许可证,用于授予系统到系统集成用户完整的组织权限 访问,同时将它们限制为仅限 API 的操作。有关详细信息,请参阅 Salesforce 帮助:仅授予集成用户 API 访问权限

REST 资源和请求

REST API 基于资源的使用情况 – 片段 Salesforce 中的数据,例如记录、记录集合、查询结果、元数据、 或 API 信息。每个资源都由统一资源标识符 (URI) 公开,并且 通过向相应的 URI 发送 HTTP 请求来访问。取决于您要访问的资源以及访问方式 构造 HTTP 请求时,可以执行多种类型的操作,包括:

  • 确定可用的 API 版本
  • Salesforce 组织的访问限制
  • 检索对象元数据
  • 创建、读取、更新和删除记录
  • 查询和搜索数据

您可以使用各种软件工具发送 HTTP 请求,这意味着确切的 请求的外观可能与本指南中的 cURL 示例不同。 但是,无论您如何提交请求,元素都不会更改。典型请求 由这些元素组成。

  • URI
  • HTTP 方法
  • 请求正文(GET 请求不需要)

URI

URI 是 Salesforce 中资源的路径。尽管 URI 从 资源到资源,基本结构保持不变。

https://MyDomainName.my.salesforce.com/services/data/vXX.X/resource/

用于安全访问资源。https://

替换为 Salesforce 组织的子域。Salesforce 在多个服务器实例上运行,因此 本指南中的示例用于代替特定的 实例。MyDomainNameMyDomainName

替换为版本 要使用的 API。您可以通过以下方式找到可用版本列表 访问 Versions 资源。XX.X

替换为 资源路径的其余部分。根据资源的不同,路径可以包含 参数,例如用于标识特定记录的 ID。您可以找到 的 URI 本指南的“参考”部分中的不同资源。resource

sObject 资源访问 Salesforce 中的标准和自定义对象。有关的信息 对象,请参阅 对象参考 Salesforce平台。

注意

URI 的某些部分区分大小写,例如 ID。URI 的其他部分不是 区分大小写,例如对象和字段名称。如果您的请求不成功, 通过将 URI 与示例进行比较,检查 URI 是否具有正确的字母大小写 在本指南中。

HTTP 方法

REST API 支持标准 HTTP 请求方法(HEAD、GET、POST、PATCH、PUT 和 DELETE),它们遵循 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 中的规范。

每种方法的用途因资源而异。有关如何操作的信息 以及何时使用每种方法,请在参考中查看该资源的页面 部分。

使用标头传递参数并自定义 HTTP 请求的选项。REST API 支持多个标准 HTTP 标头,以及特定于 到 Salesforce。

示例中使用的常见标头包括:

  • HTTP Accept – 指示客户端接受的格式 响应正文。可能的值为 和 。缺省值为 。application/jsonapplication/xmlapplication/json
  • HTTP Content-type – 指示您的请求正文的格式 附加到请求。可能的值为 和 。application/jsonapplication/xml
  • HTTP 授权 – 提供 OAuth 2.0 访问令牌以授权您的 客户。REST API 支持持有者身份验证类型。
  • 压缩标头 – 压缩请求或响应。查看更多 信息,请参阅压缩 标头。
  • 条件请求标头 – 验证您访问所依据的记录 一个前提条件。有关详细信息,请参阅条件请求 标头。

请求机构

请求正文是一个丰富的输入,可以包含在请求中以提供 其他信息,例如用于创建或更新记录的字段值。一个 请求正文可以是 JSON 或 XML 格式。

注意

使用 GET 方法访问的资源不需要附加请求 身体。

使用 HTTP Content-type 标头指示请求正文的文件格式。如果 使用 cURL 发送请求,使用 或选项。—data-binary-d

REST API 体系结构

REST API 遵循标准的 RESTful 原则和特征。
客户端-服务器
客户端应用程序独立于 Salesforce REST API,这意味着每个应用程序都是托管的 并独立更新。
无 国籍
从客户端到服务器的每个请求都必须包含所有必要的信息 了解请求,并且不要在服务器上使用任何存储的上下文。但是, 资源的表示形式使用 URI 相互连接,允许客户端 在各州之间取得进展。
缓存行为
响应被标记为可缓存或不可缓存。
统一界面
所有资源都通过 HTTPS 的通用接口进行访问。
命名资源
所有资源都使用遵循 Lightning 平台的基本 URI 进行命名 端点。有关详细信息和示例,请参阅 REST 资源和请求。
分层组件
允许在客户端和 资源。
除了标准的 RESTful 原则外,REST API 还包括其他关键特性 在其架构中,在开发 应用。

认证
REST API 支持 OAuth 2.0(一种允许安全 API 授权的开放协议)。有关更多详细信息,请参阅 Salesforce 帮助中的使用 OAuth 授权应用程序。
支持 JSON 和 XML
JSON 请求在 UTF-8 中受支持,并且是默认请求。支持 XML 请求 采用 UTF-8 和 UTF-16 格式。XML 响应以 UTF-8 格式提供。使用标头指定 JSON 或 XML。HTTP ACCEPT
在版本 57.0 及更早版本中,可以追加 URI 或向 URI 添加。例如。我们建议使用 用于指定 JSON 或 XML 的标头 相反。jsonxml/Account/001D000000INjVe.jsonHTTP ACCEPT
在版本 58.0 及更高版本中,不支持将 JSON 或 XML 追加到 URI。
压缩
压缩通过压缩 REST API 之间发送的消息来减少带宽负载 和你的客户。REST API 支持使用 gzip 和 deflate 进行压缩,定义如下 HTTP 1.1 规范。请参阅压缩标头。
条件请求
响应缓存由遵循标准的条件请求标头支持 由 HTTP 1.1 规范定义,但有一些例外。请参阅条件请求 头。
跨域资源共享
跨域资源共享 (CORS) 使 Web 浏览器能够从 出身以外的其他来源。例如,使用 CORS,JavaScript 代码位于 https://www.example.com 可以向 https://www.salesforce.com 请求资源。自 从 JavaScript 访问受支持的 Salesforce API、Apex REST 资源和 Lightning Out 代码,将提供代码的来源添加到 Salesforce CORS 允许列表。 请参阅从 Web 浏览器执行跨域请求。
Salesforce ID 长度
响应正文中的 Salesforce ID 始终为 18 个字符的 ID。在请求正文中,您 可以使用 15 个字符的 ID 或 18 个字符的 ID。
方法重写
如果使用不允许重写或 设置任意HTTP方法名称,请使用request参数。_HttpMethod
POST https://instance_name/services/data/v59.0/chatter/
/chatter/users/me/conversations/03MD0000000008KMAQ
?_HttpMethod=PATCH&read=true
注意

该参数区分大小写。用 所有值的正确大小写。_HttpMethod

HTTPS协议
客户端和服务器之间的所有通信都通过 HTTPS 进行。

通过连接的应用程序和 OAuth 2.0 进行授权

要使客户端应用程序访问 REST API 资源,必须将其授权为保险箱 游客。若要实现此授权,请使用连接的应用程序和 OAuth 2.0 授权 流。

配置连接的应用程序

连接的应用代表客户端应用程序请求访问 REST API 资源。为 连接的应用程序要请求访问权限,则必须使用 OAuth 2.0 协议。OAuth 2.0 是一种开放协议,它授权在 通过代币交换进行申请。

有关配置连接的应用程序的说明,请参阅在 Salesforce 中创建连接的应用程序 帮助。具体而言,请按照启用 API 的 OAuth 设置中的步骤操作 集成。

应用 OAuth 授权流程

OAuth 授权流授予客户端应用对 REST API 资源的受限访问权限 资源服务器。每个 OAuth 流都提供不同的流程来批准对客户端的访问 应用程序,但通常流程由三个主要步骤组成。

  1. 若要启动授权流,代表客户端应用请求的已连接应用 访问 REST API 资源。
  2. 作为响应,授权服务器将访问令牌授予连接的应用程序。
  3. 资源服务器验证这些访问令牌并批准对受保护令牌的访问 REST API 资源。

查看并选择 OAuth 授权流后,将其应用于连接的应用。为 有关每个受支持的流程的详细信息,请参阅 Salesforce 中的 OAuth 授权流程 帮助

更多资源

Salesforce 提供以下资源来帮助您浏览连接的应用程序和 OAuth:

  • Salesforce 帮助:连接的应用程序
  • Salesforce 帮助:使用以下方式授权应用程序 OAuth的
  • Salesforce 帮助:OpenID Connect 令牌 内省
  • Trailhead:使用 连接的应用程序

REST API 支持多个标准和自定义 HTTP 标头,包括两个请求 标头和响应标头。

  • 分配规则标头 分配规则标头是在创建或更新客户、案例或潜在顾客时应用的请求标头
    。如果启用,则使用活动分配规则。如果禁用,则不应用活动分配规则。如果提供了有效的 AssignmentRule ID,则应用 AssignmentRule。如果未随请求一起提供标头,则 REST API 默认使用活动分配规则。
  • 调用选项标头
    指定用于访问 REST API 资源的客户端的选项。例如,可以提供默认命名空间前缀,这样就不需要在代码中指定前缀。
  • 压缩标头
    使用压缩标头压缩 REST API 请求或响应。压缩会降低请求所需的带宽,尽管它需要客户端的更多处理能力。在大多数情况下,这种权衡有利于应用程序的整体性能。
  • 条件请求标头
    在访问资源之前,使用条件请求标头来验证资源。通过在标头中设置前提条件,可以确保仅当满足该前提条件时,请求才会成功。此功能可帮助您在更新 Salesforce 数据时防止错误并拒绝过时的请求。您可以使用条件请求标头实现各种技术,例如响应缓存。
  • 重复规则标头
    配置重复规则的选项。Salesforce 使用重复规则来查看正在创建、更新或更新插入的记录是否与现有记录重复。重复规则是重复管理的一部分。
  • 限制信息标头 此响应标头
    在对 REST API 的每个请求中返回(对版本 URI 的调用除外,这些调用不计入组织的限制)。您可以使用这些信息来监控 API 限制。/
  • 包版本标头
    指定客户端引用的每个包的版本。包版本是一个数字,用于标识包中包含的组件和行为集。此标头还可用于在调用 Apex REST Web 服务时指定包版本。
  • 查询选项标头
    指定查询中使用的选项,例如查询结果批大小。将此请求标头与查询资源一起使用。
  • 警告标头
    如果存在警告,例如使用已弃用的 API 版本,则返回此标头。

分配规则标头

分配规则标头是在创建或更新时应用的请求标头 客户、案例或潜在顾客。如果启用,则使用活动分配规则。如果禁用, 不应用活动分配规则。如果提供了有效的 AssignmentRule ID,则 应用 AssignmentRule。如果未随请求一起提供标头,则 REST API 默认为 使用活动分配规则。

标头字段名称和值

注意

在进行 REST API 调用时,也会应用此标头,这些调用间接导致 创建或更新客户、案例或潜在客户。例如,如果将此标头与 更新记录的调用,并且更新将执行更新 Case 的 Apex 触发器 将应用分配规则。字段名称Sforce-Auto-Assign字段值

  • TRUE.应用活动分配规则 创建或更新了客户、案例或潜在顾客。
  • FALSE.活动分配规则不是 适用于已创建或更新的客户、案例或潜在客户。
  • 有效的 AssignmentRule ID。给定的 AssignmentRule 应用于创建的帐户, 案例或线索。

TRUE并且不区分大小写。FALSE

如果请求中未提供标头,则默认值为 。TRUESforce-Auto-Assign: FALSE

看涨期权标题

指定用于访问 REST 的客户端的选项 API 资源。例如,您可以提供默认的命名空间前缀,以便您不 需要在代码中指定前缀。

“调用选项”标头可以与 sObject 基本信息、sObject 行、按外部 ID 划分的 sObject 行、Query、QueryAll、 和搜索。 批量 API 和批量 API 2.0 也支持它。

标头字段名称和值

字段名称Sforce-Call-Options字段值

  • client– 用作 发送请求的客户端的标识符。此字符串 显示在日志文件中,帮助您跟踪哪个客户端发送了 请求。
  • defaultNamespace——答 开发人员命名空间前缀用作 请求。使用此标头字段,请求将解析 没有指定命名空间的托管包。(不支持 批量 API。

如果 developer 命名空间前缀为 ,并且 您在包中有一个名为 botId 的自定义字段,请将 带有调用选项的默认命名空间 页眉:

battle

Sforce-Call-Options: client=caseSensitiveToken; defaultNamespace=battle

然后 如下所示的查询成功:

/services/data/vXX.X/query/?q=SELECT+Id+botID__c+FROM+Account

在本例中,实际查询的字段是battle__botId__c字段。

使用此标头可以编写客户端代码,而无需指定 命名空间前缀。在前面的示例中,如果没有标头,则必须编写 battle__botId__c。

如果设置了此字段,并且查询还指定了命名空间,则响应 不包含前缀。例如,如果将此标头设置为 ,并发出类似 的查询,则 response 使用元素,而不是元素。battleSELECT+Id+battle__botID__c+FROM+AccountbotId__cbattle_botId__c

当出现以下情况时,该字段将被忽略 检索描述信息,避免命名空间前缀之间的歧义 和同名的客户字段。defaultNamespace

压缩标头

使用压缩标头压缩 REST API 请求或响应。压缩减少 请求所需的带宽,尽管它需要客户端的更多处理能力。 在大多数情况下,这种权衡有利于应用程序的整体性能。

REST API 支持 HTTP 1.1 定义的 gzip 和 deflate 压缩算法 规范。如果您不确定使用哪一个,gzip 比 deflate 更常见。

提示

为了获得更好的性能,我们建议客户端接受并支持压缩 由 HTTP 1.1 规范定义。

请求压缩

包括 or 标头以压缩请求。REST API 在处理之前解压缩任何请求。Content-Encoding: gzipContent-Encoding: deflate

此示例请求使用 gzip 压缩。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H "Authorization: Bearer access-token" -H "Content-Type: application/json" -H "Content-Encoding: gzip" —data-binary @new-account.json -X POST

响应压缩

仅当请求包含 or 标头时,Salesforce 才会压缩响应。即使有 指定了 Accept-Encoding,但它通常会这样做。如果压缩,则响应包含 带有压缩算法的 Content-Encoding 标头,以便客户端知道解压缩 它。Accept-Encoding: gzipAccept-Encoding: deflate

此示例请求请求压缩响应。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/0015e000009sS0DAAU -H "Authorization: Bearer access-token" -H "Content-Type: application/json" -H "Accept-Encoding: gzip" -X GET

条件请求标头

在访问资源之前,使用条件请求标头来验证资源。由 在标头中设置一个前提条件,确保只有在 满足前提条件。此功能可帮助您防止错误并拒绝过时的请求 更新 Salesforce 数据时。您可以使用条件实现各种技术 请求标头,例如响应缓存。

条件请求标头提供两种类型的验证:强验证和弱验证。 强验证检查前提条件是否与 Salesforce 中的资源完全匹配。 强验证标头包括 和 ,它们使用实体标记 (ETag) 来比较 Salesforce 中记录的前提条件。If-MatchIf-None-Match

弱验证会根据 Salesforce 中的资源检查前提条件,但事实并非如此 保证两者相同。弱验证标头包括 或 ,它将前提条件与 Salesforce 中的记录。If-Modified-SinceIf-Unmodified-SinceREST API 条件标头遵循 HTTP 1.1 规范,但存在以下例外情况。

  • 如果为 、 或 PATCH 或 POST 请求包含无效的标头值,则返回状态代码。If-MatchIf-None-MatchIf-Unmodified-Since400 Bad Request
  • 不支持标头。If-Range
  • 不支持 DELETE 请求

ETag (英语)

标头是返回的响应标头 访问 sObject Rows 资源时。它是后续请求中 和 请求标头使用的内容的哈希值,用于确定内容是否 已更改。ETagIf-MatchIf-None-Match

sObject 行(仅限客户记录)资源支持此标头。

此示例显示了 REST API 返回的。ETag

ETag: "U5iWijwWbQD18jeiXwsqxeGpZQk=-gzip"

您可以在 www.w1.org/Protocols/rfc1/rfc3-sec2616.html#sec2616.14 中找到标头的 HTTP 14.19 规范。ETag

如果匹配

标头是 sObject 的请求标头 包含 ETag 列表的行。如果请求的记录的 ETag 匹配 在标头中指定为前提条件的 ETag,则处理请求。否则,一个 412 返回前提条件失败状态代码,并且不处理请求。If-Match

此标头支持 sObject 行(仅限客户记录)资源。

在此示例中,标头包含在 请求。If-Match

If-Match: "Jbjuzw7dbhaEG3fd90kJbx6A0ow=-gzip", "U5iWijwWbQD18jeiXwsqxeGpZQk=-gzip"

您可以在 www.w1.org/Protocols/rfc1/rfc3-sec2616.html#sec2616.14 中找到标头的 HTTP 14.24 规范。If-Match

如果-无匹配

标头是 sObject 行,与 相反。如果 您请求的记录的 ETag 与标头中指定的 ETag 匹配,即 请求未得到处理。为 GET 或 HEAD 返回 304 未修改状态代码 请求,并且 PATCH 请求返回 412 前提条件失败状态代码。If-None-MatchIf-Match

此标头支持 sObject 行(仅限客户记录)资源。

在此示例中,包含一个标头 有请求。If-None-Match

If-None-Match: "Jbjuzw7dbhaEG3fd90kJbx6A0ow=-gzip", "U5iWijwWbQD18jeiXwsqxeGpZQk=-gzip"

您可以在 www.w1.org/Protocols/rfc1/rfc3-sec2616.html#sec2616.14 中找到标头的 HTTP 14.26 规范。If-None-Match

如果修改后

标头是基于时间的请求 页眉。仅当数据自日期和时间以来发生更改时,才会处理请求 在标头中指定。否则,将返回 304 Not Modified 状态代码,并且 请求未得到处理。If-Modified-Since

此标头支持 sObject Rows、sObject 描述、描述全局和可调用 操作资源。

在此示例中,标头是 包含在请求中。If-Modified-Since

If-Modified-Since: Tue, 10 Aug 2015 00:00:00 GMT

您可以在 www.w1.org/Protocols/rfc1/rfc3-sec2616.html#sec2616.14 中找到标头的 HTTP 14.25 规范。If-Modified-Since

如果未修改,则自

标头是请求标头 这是 的反面。如果你做一个 request 并包含 If-Unmodified-Since 标头,则 REST API 仅在以下情况下处理请求 自指定日期以来,数据未发生更改。否则,412 前提条件将失败 返回状态代码,并且不处理请求。If-Unmodified-SinceIf-Modified-Since

此标头支持 sObject Rows、sObject 描述、描述全局和可调用 操作资源。

在此示例中,标头为 包含在请求中。If-Unmodified-Since

If-Unmodified-Since: Tue, 10 Aug 2015 00:00:00 GMT

您可以在 www.w1.org/Protocols/rfc1/rfc3-sec2616.html#sec2616.14 中找到标头的 HTTP 14.28 规范。If-Unmodified-Since

重复的规则标头

配置重复规则的选项。Salesforce 使用 复制规则,用于查看正在创建、更新或更新插入的记录是否为重复记录 现有记录。重复规则是重复管理的一部分。

此标头在 API 版本 52.0 及更高版本中可用。

标头字段名称和值

所有字段的默认值均为 。false字段名称allowSave字段值

  • true– 允许用户确认警报 并保存重复的记录。如果为操作启用了警报,则适用。
  • false– 不允许用户确认 警报或保存重复的记录。如果为操作启用了警报,则适用。

字段名称includeRecordDetails字段值

  • true– 返回重复项中的所有字段 记录。
  • false– 返回重复的记录 ID,但不返回 字段。

字段名称runAsCurrentUser字段值

  • true– 运行重复规则时,使用 当前用户的共享规则。
  • false– 运行重复规则时,使用 系统共享规则,而不是当前用户的共享规则。

允许用户确认警报并保存重复记录。指示 将返回重复字段的记录,并强制执行当前用户的共享规则。 现在,在创建记录时应用这些重复的管理配置选项。 更新和更新插入。

Sforce-Duplicate-Rule-Header: allowSave=true, includeRecordDetails=true, runAsCurrentUser=true

限制信息标题

在对 REST API 的每个请求中都会返回此响应标头(对版本 URI 的调用除外,这些调用不计入组织的限制)。您可以使用这些信息来监控 API 限制。/

标头字段名称和值

字段名称Sforce-Limit-Info字段值

  • api-usage– 指定进行调用的组织的每日 API 使用情况。第一个数字是数字 使用的 API 调用,第二个数字是组织的 API 限制。

标头中返回的值表示标准 REST API 限制和用法。 除非使用 Salesforce Functions 进行调用。使用 Salesforce 拨打的电话 函数从特定于函数的分配中获取。例Sforce-Limit-Info: api-usage=10018/100000

包版本标头

指定 客户。包版本是标识组件和行为集的数字 包含在包中。 此标头还可用于指定包版本 调用 Apex REST Web 服务时。

Package Version 标头可与以下资源一起使用:Describe Global、sObject Describe、 sObject 基本信息、sObject 行、 按外部 ID 划分的 sObject 布局、Query、QueryAll、Search 和 sObject 行。

标头字段名称和值

字段名称和值x-sfdc-packageversion-[namespace]: xx.x,其中 是托管包的唯一命名空间,是包版本。[namespace]xx.xx-sfdc-packageversion-clientPackage: 1.0

查询选项标头

指定查询中使用的选项,例如查询结果批处理 大小。将此请求标头与查询一起使用 资源。

标头字段名称和值

字段名称Sforce-Query-Options字段值

  • batchSize– 指定 为查询请求返回的记录数。子对象计入 批大小的记录。例如,在关系查询中,多个子项 每个返回的父行返回对象。默认值为 2,000; 最小值为 200,最大值为 2,000。不能保证请求的 批处理大小是实际的批处理大小。根据需要进行更改以最大化 性能。

Sforce-Query-Options: batchSize=1000

警告标头

如果存在警告,例如使用已弃用的 API 版本,则返回此标头。

标头字段名称和值

字段名称Warning字段值warningCode warningMessage有关已弃用的 API 版本的警告,请 .warningCode299

Warning: 299 - "This API is deprecated and will be removed by Summer '22. Please see https://help.salesforce.com/articleView?id=000351312 for details."

使用 cURL 发送 REST 请求

本指南中的示例使用 cURL 工具发送 HTTP 请求,这些请求访问 在 Salesforce 中创建和操作资源。如果您使用其他工具发送 requests,您可以使用 cURL 示例中的相同元素来发送请求。

cURL 预装在许多 Linux 和 macOS 系统上。Windows 用户可以下载 版本为 curl.haxx.se/。在 Windows 上使用 HTTPS 时,请确保您的系统满足 SSL 的 cURL 要求。

注意

cURL 是一个开源工具,不受 Salesforce的。

附加请求正文

许多示例包括请求正文 – 包含 请求。使用 cURL 时,请将这些文件保存到本地系统并附加它们 使用 —data-binary 或 -d 选项添加到请求中。

此示例附加 new-account.json 文件。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/sobjects/Account/ -H "Authorization Bearer access-token" -H “Content-Type: application/json” —data-binary @new-account.json -X POST

处理访问令牌中的感叹号

运行 cURL 示例时,由于以下原因,在 macOS 和 Linux 系统上可能会出现错误 OAuth 访问令牌中是否存在感叹号 (!) 特殊字符。 若要避免出现此错误,请转义感叹号或使用单个 引号。

若要对访问令牌中的感叹号进行转义,请在其前插入反斜杠 (\!) 当访问令牌括在双引号内时。例如,访问 此 cURL 命令中的令牌字符串具有感叹号 (!) 转义。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H "Authorization: Bearer 00D50000000IehZ\!AQcAQH0dMHZfz972Szmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1E6LYUfiDUkWe6H34r1AAwOR8B8fLEz6n04NPGRrq0FM"

或者,可以将访问令牌括在单引号内。

curl https://MyDomainName.my.salesforce.com/services/data/v59.0/ -H 'Authorization: Bearer 00D50000000IehZ!AQcAQH0dMHZfz972Szmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1E6LYUfiDUkWe6H34r1AAwOR8B8fLEz6n04NPGRrq0FM'

配置 Salesforce CORS 允许列表

跨域资源共享 (CORS) 允许 Web 浏览器请求 来自其他来源的资源。例如,使用 CORS,https://www.example.com Web 应用程序的 JavaScript 可以从 https://www.salesforce.com 请求资源。要允许访问受支持的 Salesforce API,请执行以下操作: Apex REST 资源和 Web 浏览器中 JavaScript 代码的 Lightning Out,添加请求 源添加到您的 Salesforce CORS 允许列表。对于允许 Web 浏览器制作的 Lightning 应用程序 来自其组织的请求,CORS 允许列表会阻止对 Lightning 应用程序的请求,除非请求 来自已批准的 URL。

适用于:Salesforce Classic(并非在所有组织中都可用)和 闪电体验
适用于:DeveloperEnterprisePerformance 和 Unlimited Edition
在以下版本中启用 API 访问时可用:专业版
所需的用户权限
要创建、读取、更新和删除,请执行以下操作:修改所有数据

这些 Salesforce 技术支持 CORS。

  • Apex REST的
  • 批量 API
  • 批量 API 2.0
  • 连接 REST API
  • 闪电输出
  • REST API
  • CRM 分析 REST API
  • 用户界面 API

将提供请求代码的源添加到 CORS 允许列表。如果支持 CORS 的浏览器 向允许列表中的源发出请求,Salesforce 会在 HTTP 标头中返回源以及任何其他 CORS HTTP 标头。如果源未包含在允许列表中,Salesforce 将返回 HTTP 状态 代码 403。Access-Control-Allow-Origin

  1. 在“设置”的“快速查找”框中,输入 CORS,然后选择“CORS”。
  2. 选择新建
  3. 在 Origin URL Pattern 中输入资源。提示源 URL 模式并不总是与 浏览器的地址栏。
  4. 保存更改。

源 URL 模式必须包含 HTTPS 协议(除非您使用的是 localhost) 和域名。它还可以包括端口。支持通配符 (*),并且必须 在二级域名前面。例如,https://*.example.com 会将 example.com 的所有子域名添加到许可名单中。

源 URL 模式可以是 IP 地址。但是 IP 地址和解析为 同一地址不是同一来源,您必须将它们单独添加到 CORS 允许列表中 条目。

允许将 Google Chrome™ 和 Mozilla® Firefox® 浏览器扩展作为 API 中的资源 版本 53 (Winter ’22) 或更高版本。Chrome 扩展程序必须使用前缀和 32 个字符,不带数字或大写字母 字母,例如.Firefox 扩展必须使用 前缀和 8-4-4-4-12 小字母数字字符的格式,例如 。chrome-extension://chrome-extension://abdkkegmcbiomijcbdaodaflgehfffedmoz-extension://moz-extension://1234ab56-78c9-1df2-3efg-4567891hi1j2

在 CORS 预检测试中请求 REST 资源时,您可以获得成功的响应。 但收到对实际请求的不成功响应。当 资源在印前检查测试之后和发出请求之前被删除。它也可能发生 如果资源不存在。CORS 预检确认资源是否可以在 服务器,但不检查特定资源是否存在。 CORS 预检请求是 通常由浏览器自动发出。

注意

要使用 CORS 访问某些 OAuth 端点,需要满足其他要求。请参阅为 OAuth 端点启用 CORS。

有效的日期和日期时间格式

为 和 字段指定正确的格式。

dateTimedate

日期时间

使用 or 格式指定字段。yyyy-MM-ddTHH:mm:ss.SSS+/-HH:mmyyyy-MM-ddTHH:mm:ss.SSSZdateTime

  • yyyy 是四位数的年份
  • MM 是两位数的月份 (01-12)
  • dd 是两位数的日期 (01-31)
  • “T”是一个分隔符,表示一天中的时间紧随其后
  • HH 是两位数小时 (00-23)
  • mm 是两位数的分钟 (00-59)
  • ss 是两位数秒 (00-59)
  • SSS 是可选的三位数毫秒 (000-999)
  • +/-HH:mm 是祖鲁 (UTC) 时区偏移量
  • “Z”是参考 UTC 时区

将时区添加到 UTC 时, result 是该时区的日期和时间。例如,2002-10-10T12:00:00+05:00 是 2002-10-10T07:00:00Z,2002-10-10T00:00:00+05:00 是 2002-10-09T19:00:00Z。请参阅 W3C XML 架构第 2 部分:DateTime 数据类型。dateTime

日期

使用格式指定字段。yyyy-MM-dddate

注意

不支持指定偏移量。date

状态代码和错误响应

当发生错误或响应成功时,响应标头 包含 HTTP 代码,响应正文通常包含:

  • HTTP 响应代码
  • HTTP 响应代码附带的消息
  • 发生错误的字段或对象(如果响应返回信息 关于错误)
HTTP 响应代码描述
200“OK”成功代码,用于 GET、HEAD 和一些 PATCH 请求。
201“创建”成功代码, 用于 POST 请求和一些 PATCH 请求。
204“无内容”成功 代码,用于 DELETE 请求和一些 PATCH 请求。
300外部 ID 时返回的值 存在于多个记录中。响应正文包含列表 的匹配记录。
304请求内容未更改 自指定日期和时间起。提供日期和时间 在标题中。请参阅获取对象 Metatdata Changes 为例。If-Modified-Since
400请求无法理解, 通常是因为 JSON 或 XML 正文包含错误。
401使用的会话 ID 或 OAuth 令牌具有 已过期或无效。响应正文包含 和 。messageerrorCode
403该请求已被拒绝。验证 登录用户具有适当的权限。如果错误 代码已REQUEST_LIMIT_EXCEEDED,则超出了 API 请求限制 在您的组织中。
404请求的资源不能是 发现。检查 URI 是否存在错误,并验证是否没有 共享问题。
405中指定的方法 不允许对 URI。
409由于原因,请求无法完成 与资源的当前状态发生冲突。检查 API 版本与你的资源兼容 请求。
410请求的资源已停用或删除。删除或更新 对资源的任何引用。
412请求未执行,因为 或客户端在 请求标头不满意。例如,请求包括 一个 If-Unmodified-Since 标头,但数据 在指定日期之后被修改。
414URI 的长度超过 16,384 字节限制。
415请求中的实体位于 指定不支持的格式 方法。
420Salesforce Edge 没有可用于此的路由信息 请求主机。联系 Salesforce 客户支持。
428请求未执行,因为它不是有条件的。添加以下一项 条件请求标头,例如 、和 重新提交。If-Match
431URI 和 标头超过 16,384 字节的限制。
500闪电网络中发生错误 平台,因此无法完成请求。联系 Salesforce 客户支持。
502Salesforce Edge 无法与 Salesforce 实例。
503服务器无法处理 请求。通常,如果服务器已关闭,则会出现此问题 维护或超载。

不正确的 ID 示例在使用 JSON 或 XML 的请求中使用不存在的 ID (request_body.json 或 request_body.xml)

[
{
  "fields" : [ "Id" ],
  "message" : "Account ID: id value of incorrect type: 001900K0001pPuOAAU",
  "errorCode" : "MALFORMED_ID"
}
]

资源不存在请求不存在的资源,例如,您尝试创建一个 使用拼写错误的对象进行记录 名字

[
{
  "message" : "The requested resource does not exist",
  "errorCode" : "NOT_FOUND"
}
]

API 生命周期终止政策

查看哪些 REST API 版本受支持、不受支持或不可用。

Salesforce 承诺支持每个 API 版本至少 3 个 自首次发布之日起的年。为了提高质量和性能 API,有时不再支持超过 3 年的版本。

Salesforce 通知使用计划的 API 版本的客户 为 折旧 至少 1 年后,对版本的支持将结束。

Salesforce API 版本版本支持状态版本停用信息
版本 31.0 至 59.0支持。
版本 21.0 至 30.0截至 22 年夏季,这些版本已被弃用,并且没有 Salesforce 支持的时间更长。从 25 年夏季开始,这些 版本将停用且不可用。Salesforce Platform API 版本 21.0 到 30.0 停用
版本 7.0 至 20.0自 22 年夏季起,这些版本已停用,并且 不能利用的。Salesforce Platform API 版本 7.0 到 20.0 停用

如果你 请求任何资源或使用已停用的 API 版本 REST API 中的操作 返回错误代码。410:GONE

识别 从旧的或不受支持的 API 版本发出的请求,请使用 API 总使用量事件类型。

使用Heroku运行Salesforce Canvas应用程序

学习目标

完成本单元后,您将能够:

  • 了解Canvas应用程序的身份验证过程。
  • 了解如何使用Heroku运行Salesforce Canvas应用程序。

Salesforce Canvas

使用Salesforce Canvas,您可以将在Heroku上运行的UI或Web应用程序嵌入到Salesforce UI中。Canvas的主要优势是能够使用大量的开源Web技术来构建可轻松与Salesforce集成的Web应用程序。Canvas SDK在Web应用程序中使用JavaScript来访问用户有权访问的Salesforce数据。您可以在本地计算机上开发Canvas应用程序,并使用典型的开发人员流程进行变更管理和部署。

在幕后,Canvas应用程序通过iframe加载到Salesforce中。当然,您可以通过iframe将任何Web应用程序加载到Salesforce的UI中,但使用Canvas,您可以通过JavaScript使用安全通信协议与Salesforce进行通信。当您需要超出Canvas JavaScript API实现的功能时,您可以将Canvas处理的身份验证与Salesforce REST API结合使用,可能使用像JSforce这样的REST API包装器 。

该图表显示Heroku应用程序可以通过Canvas Javascript桥与Salesforce交互

认证

Canvas应用程序在Salesforce中使用已连接的应用程序,可以使用已 签名的请求或典型的 OAuth流来处理身份验证。签名请求方法的一个优点是,当Salesforce管理员允许用户访问Canvas应用程序时,应用程序无需中间授权即可向Salesforce发出请求。加载Canvas应用程序后,应用程序可以开始访问用户有权访问的Salesforce数据。

在Heroku上运行Canvas应用程序时,应用程序需要连接应用程序的消费者秘密,该秘密通过Heroku Config Var提供给应用程序,可作为环境变量提供给应用程序。

基本画布应用程序

基本的Canvas应用加载Canvas SDK JavaScript库:

<script type="text/javascript" src="https://.salesforce.com/canvas/sdk/js/36.0/canvas-all.js"></script>
<script type="text/javascript">
    // callback to access the OAuth access token and context object
    Sfdc.canvas(function() {
        // Save the token
        Sfdc.canvas.oauth.token(window.signedRequestJson.oauthToken);
        window.alert("hello, " + window.signedRequestJson.context.user.fullName);
    });
</script>

应用程序的 上下文数据取决于应用程序在Salesforce中的运行位置。您可以将Canvas应用加载到Chatter提要,Chatter选项卡,布局,移动卡,发布者操作和VisualForce页面中。每个都可以为Canvas应用程序提供不同的上下文。例如,如果Canvas应用程序在帐户页面的布局中呈现,则上下文包含帐户的数据。然后,Canvas应用程序中的JavaScript可以使用该数据来呈现信息。

使用Heroku运行Salesforce Canvas应用程序

学习目标

完成本单元后,您将能够:

  • 了解Canvas应用程序的身份验证过程。
  • 了解如何使用Heroku运行Salesforce Canvas应用程序。

Salesforce Canvas

使用Salesforce Canvas,您可以将在Heroku上运行的UI或Web应用程序嵌入到Salesforce UI中。Canvas的主要优势是能够使用大量的开源Web技术来构建可轻松与Salesforce集成的Web应用程序。Canvas SDK在Web应用程序中使用JavaScript来访问用户有权访问的Salesforce数据。您可以在本地计算机上开发Canvas应用程序,并使用典型的开发人员流程进行变更管理和部署。

在幕后,Canvas应用程序通过iframe加载到Salesforce中。当然,您可以通过iframe将任何Web应用程序加载到Salesforce的UI中,但使用Canvas,您可以通过JavaScript使用安全通信协议与Salesforce进行通信。当您需要超出Canvas JavaScript API实现的功能时,您可以将Canvas处理的身份验证与Salesforce REST API结合使用,可能使用像JSforce这样的REST API包装器 。

该图表显示Heroku应用程序可以通过Canvas Javascript桥与Salesforce交互

认证

Canvas应用程序在Salesforce中使用已连接的应用程序,可以使用已 签名的请求或典型的 OAuth流来处理身份验证。签名请求方法的一个优点是,当Salesforce管理员允许用户访问Canvas应用程序时,应用程序无需中间授权即可向Salesforce发出请求。加载Canvas应用程序后,应用程序可以开始访问用户有权访问的Salesforce数据。

在Heroku上运行Canvas应用程序时,应用程序需要连接应用程序的消费者秘密,该秘密通过Heroku Config Var提供给应用程序,可作为环境变量提供给应用程序。

基本画布应用程序

基本的Canvas应用加载Canvas SDK JavaScript库:

<script type="text/javascript" src="https://.salesforce.com/canvas/sdk/js/36.0/canvas-all.js"></script>
<script type="text/javascript">
    // callback to access the OAuth access token and context object
    Sfdc.canvas(function() {
        // Save the token
        Sfdc.canvas.oauth.token(window.signedRequestJson.oauthToken);
        window.alert("hello, " + window.signedRequestJson.context.user.fullName);
    });
</script>

应用程序的 上下文数据取决于应用程序在Salesforce中的运行位置。您可以将Canvas应用加载到Chatter提要,Chatter选项卡,布局,移动卡,发布者操作和VisualForce页面中。每个都可以为Canvas应用程序提供不同的上下文。例如,如果Canvas应用程序在帐户页面的布局中呈现,则上下文包含帐户的数据。然后,Canvas应用程序中的JavaScript可以使用该数据来呈现信息。