---
schema_version: "1"
id: f330abe0a9c836d8a50e563b4079e6f3d61cbc7e645692218f7cecb5b0cc9d86
title: 集成模式
collection: architect
version: next
locale: zh-cn
portal_url: https://docs.salesforce.com/architect/next/zh-cn/fundamentals/guides/integration-patterns.md
canonical_url: https://staging.architect.salesforce.com/docs/architect/zh-cn/fundamentals/guide/integration-patterns.html
source_site: staging.architect.salesforce.com
content_type: documentation
content_hash: d7b2d893e01ec21a33cad0bf745fd7f83832205225d159013aaa2f5f55c718a9
products:
  - 基本知识
  - Architect Site Content Repo
updated_at: 2025-10-01T00:00:00Z
---
## 集成模式概览

通常，当您实施 Salesforce 时，您需要将其与其他应用程序集成。虽然每个集成场景都是唯一的，但是开发人员和架构师必须解决一些共同的要求和问题。

本文档描述了这些常见集成场景的策略（模式形式）。每个模式描述了特定场景的设计和方法，而不是详细描述特定的实施。在本文档中，您将找到：

- 解决关键“原型”集成场景的一些模式
- 选择矩阵有助于确定哪种模式最适合您的场景
- 集成提示和最佳实践

**目的和范围**

本文档适用于需要将 Salesforce Platform 与企业中的其他应用程序集成的设计者和架构师。此内容是 Salesforce 架构师和合作伙伴许多成功实施的提炼。

要熟悉大规模采用基于 Salesforce 的应用程序可用的集成功能和选项，请阅读模式汇总和模式选择指南。架构师和开发人员应该在 Salesforce 集成项目的设计和实施阶段考虑这些模式详细信息和最佳实践。

如果实施正确，这些模式使您能够尽快投入生产，并拥有尽可能稳定、可扩展和免维护的应用程序集。Salesforce 自己的咨询架构师在架构审查期间将这些模式用作参考点，并积极维护和改进它们。

与所有模式一样，本内容涵盖了大多数集成场景，但不是全部。虽然 Salesforce 允许用户界面 (UI) 集成，例如，混搭，但这种集成不属于本文档的范围。

**模式模板**

每个集成模式遵循一致的结构。这使得每个模式中提供的信息具有一致性，也使得比较模式更加容易。

_名称_

模式标识符，也指示模式中包含的集成类型。

_上下文_

模式解决的整体集成场景。上下文提供有关用户尝试完成什么以及应用程序将如何行为来支持要求的信息。

_问题_

模式旨在解决的场景或问题（以问题表示）。查看模式时，请阅读本节，以快速了解模式是否适合您的集成场景。

_武力_

使所述场景难以解决的约束和环境。

_解决方案_

解决集成场景的推荐方式。

_草图_

UML 序列图，向您展示了解决方案如何解决场景。

_结果_

解释如何将解决方案应用到集成场景的详细信息，以及它如何解决与该场景相关联的因素。本节还包含应用模式后可能出现的新挑战。

_侧栏_

与模式相关的其他部分包含关键技术问题、模式的变体、特定于模式的注意事项等。

_示例_

一个端到端的场景，描述了如何在真实世界的 Salesforce 场景中使用设计模式。该示例解释了集成目标以及如何实施模式来实现这些目标。

**模式汇总**

下表列出了本文档中包含的集成模式。

_模式列表_
remote-process-invocation--request-and-reply

<table>
    <tr>
        <th scope="col">模式</th>
        <th scope="col">场景</th>
    </tr>
    <tr>
        <td><a href="#远程进程调用--请求和回复">远程流程调用 — 请求和回复</a></td>
        <td>Salesforce 调用远程系统上的进程，等待该进程完成，然后根据远程系统的响应跟踪状态。</td>
    </tr>
    <tr>
        <td><a href="#远程进程调用--触发并忘记">远程进程调用 — 触发并忘记</a></td>
        <td>Salesforce 调用远程系统中的进程，但不等待进程完成。相反，远程进程接收并确认请求，然后将控制切换回 Salesforce。</td>
    </tr>
    <tr>
        <td><a href="#batch-data-synchronization">批处理数据同步</a></td>
        <td>创建或刷新存储在 Lightning 平台中的数据，以反映来自外部系统的更新，以及 Lightning 平台的更改何时发送到外部系统。无论哪个方向的更新都是以批处理的方式进行的。</td>
    </tr>
    <tr>
        <td><a href="#远程呼叫">远程呼叫</a></td>
        <td>存储在 Salesforce Platform 中的数据由远程系统创建、检索、更新或删除。</td>
    </tr>
    <tr>
        <td><a href="#基于数据更改的-ui-更新">基于数据更改的 UI 更新</a></td>
        <td>由于 Salesforce 数据的更改，Salesforce 用户界面必须自动更新。</td>
    </tr>
    <tr>
        <td><a href="#数据虚拟化">数据虚拟化</a></td>
        <td>Salesforce 实时访问外部数据。这消除了在 Salesforce 中保留数据，然后在 Salesforce 和外部系统之间协调数据的需要。</td>
    </tr>
</table>

**模式方法**

本文档中的集成模式分为三类：

- 数据集成 — 这些模式解决了同步驻留在两个或多个系统中的数据的要求，以便两个系统始终包含及时和有意义的数据。数据集成通常是最简单的集成实施类型，但需要适当的信息管理技术，以使解决方案具有可持续性和成本效益。此类技术通常包括主数据管理 (MDM)、数据治理、主数据、重复数据消除、数据流设计等方面。

- 流程集成 - 此类别的模式满足业务流程利用两个或多个应用程序完成任务的需求。当您为这种类型的集成实施解决方案时，触发应用程序必须跨进程边界调用其他应用程序。通常，这些模式还包括编排（其中一个应用程序是中央“控制器”）和编排（应用程序是多个参与者，没有中央“控制器”）。这些集成通常需要复杂的设计、测试和异常处理要求。此外，此类复合应用程序通常对基础系统的要求更高，因为它们通常支持长时间运行的事务，以及报告或管理进程状态的能力。

- 虚拟集成 — 此类别的模式可满足用户查看、搜索和修改存储在外部系统中的数据的需求。当您为这种类型的集成实施解决方案时，触发应用程序必须调用其他应用程序并实时与其数据进行交互。这种类型的集成消除了跨系统的数据复制需求，并意味着用户始终与最新的数据进行交互。

为您的系统选择最佳集成策略并非易事。需要考虑很多方面，可以使用很多工具，有些工具比其他工具更适合某些任务。每个模式都解决了特定的关键区域，包括每个系统的功能、数据量、故障处理和事务性。

**模式选择指南**

选择矩阵表列出了模式及其关键方面，以帮助您确定哪个模式最适合您的集成要求。使用这些维度对模式进行分类。

<table>
    <tr>
        <th scope="col">方面</th>
        <th scope="col">描述</th>
    </tr>
    <tr>
        <td>类型</td>
        <td>指定集成样式：进程、数据或虚拟。
          <ul>
                <li>进程：基于进程的集成是集成两个或多个应用程序之间功能流处理的方式。这些集成通常涉及更高级别的抽象和复杂性，特别是对于事务性和回滚。
                </li>
                <li>数据：数据集成是应用程序使用信息的集成。这些集成的范围可以从简单的表格插入或更新插入到需要引用完整性和复杂翻译的复杂数据更新。 
                </li>
                <li>虚拟：虚拟集成是 Salesforce 与驻留在外部系统中的数据进行交互的地方，无需复制 Salesforce 中的数据。这种类型的集成总是通过来自 Salesforce 平台的事件触发，例如用户操作、搜索或记录更新，导致与外部源的实时数据集成。
                </li>
          </ul>
        </td>
    </tr>
    <tr>
        <td>时间</td>
        <td>指定集成样式：进程、数据或虚拟。
          <ul>
            <li>同步：阻止和实时请求是请求/响应操作。通过此操作，结果会立即返回到调用者。
            </li>
            <li>异步 - 近乎实时的单向操作调用非阻止、队列或基于消息的请求。通过调用其他单向操作，返回结果和任何错误。因此，调用者提出请求并继续，无需等待响应。
            </li>
          </ul>
        </td>
    </tr>
</table>

_将 Salesforce 与其他系统集成_

此表列出了模式及其关键方面，以帮助您确定在从 Salesforce 集成到另一个系统时哪个模式最适合您的要求。

<table class="guide-table table" style="border: 0px;">
    <tr>
        <th scope="col">类型</th>
        <th scope="col">时间</th>
        <th scope="col">要考虑的关键模式</th>
    </tr>
    <tr>
        <td>流程集成</td>
        <td>Synchronous</td>
        <td><a href="#远程进程调用--请求和回复">远程流程调用 — 请求和回复</a></td>
    </tr>
    <tr>
        <td>流程集成</td>
        <td>Asynchronous</td>
        <td><a href="#远程进程调用--触发并忘记">远程进程调用 — 触发并忘记</a></td>
    </tr>
    <tr>
        <td>数据集成</td>
        <td>Synchronous</td>
        <td><a href="#远程进程调用--请求和回复">远程流程调用 — 请求和回复</a></td>
    </tr>
    <tr>
        <td>数据集成</td>
        <td>Asynchronous</td>
        <td><a href="#基于数据更改的-ui-更新">基于数据更改的 UI 更新</a></td>
    </tr>
    <tr>
        <td>虚拟集成</td>
        <td>Synchronous</td>
        <td><a href="#数据虚拟化">数据虚拟化</a></td>
    </tr>
</table>

_将其他系统集成到 Salesforce_

此表列出了模式及其关键方面，以帮助您确定从另一个系统集成到 Salesforce 时最适合需求的模式。

<table class="guide-table table" style="border: 0px;">
    <tr>
        <th scope="col">类型</th>
        <th scope="col">时间</th>
        <th scope="col">要考虑的关键模式</th>
    </tr>
    <tr>
        <td>流程集成</td>
        <td>Synchronous</td>
        <td><a href="#远程呼叫">远程呼叫</a></td>
    </tr>
    <tr>
        <td>流程集成</td>
        <td>Asynchronous</td>
        <td><a href="#远程呼叫">远程呼叫</a></td>
    </tr>
    <tr>
        <td>数据集成</td>
        <td>Synchronous</td>
        <td><a href="#远程呼叫">远程呼叫</a></td>
    </tr>
    <tr>
        <td>数据集成</td>
        <td>Asynchronous</td>
        <td><a href="#batch-data-synchronization">批处理数据同步</a></td>
    </tr>
</table>

**中间件术语和定义**

此表列出了一些与中间件相关的关键术语，以及这些模式的定义。

<table>
    <tr>
        <th scope="col">术语</th>
        <th scope="col">定义</th>
    </tr>
    <tr>
        <td>事件处理</td>
        <td>事件处理是在指定的接收方（“处理器”）接收可识别的事件。事件处理涉及的关键流程包括：<br/> <br/> 
        <ul>
            <li>确定事件的转发位置</li>
            <li>执行转发操作</li>
            <li>接收转发的事件</li>
            <li>采取某种适当的响应措施，例如写入日志、发送错误或恢复过程或发送额外消息</li>
        </ul>
        <br/>
        请记住，事件处理器最终可以将事件转发给事件使用者。<br/> <br/> 
        此功能与中间件的常见使用可以扩展到包括流行的“发布/订阅”或“发布/订阅”功能。在发布/订阅场景中，中间件将请求或消息从活动数据事件发布者路由到活动数据事件订阅者。然后，这些拥有活跃听众的消费者可以在事件发布时检索它们。 <br/> 
        在使用中间件的 Salesforce 集成中，中间件层承担对事件处理的控制。它收集所有相关事件（同步或异步），并管理到所有端点（包括 Salesforce）的分发。 <br/> <br/> 
        或者，可以通过 Salesforce 企业消息传递平台通过将事件总线与平台事件一起使用来实现此功能。<br/> </td>
    </tr>
    <tr>
      <td>协议转换</td>
      <td>协议转换通常是一个软件应用程序，将一个设备的标准或专有协议转换为适用于另一个设备的协议，以实现互操作性。<br/> <br/> 
      在中间件的上下文中，与特定目标系统的连接可能受到协议的约束。在这种情况下，需要将消息格式转换为目标系统的格式或封装在该格式中，以便提取负载。这也被称为隧道。<br/>
      Salesforce 不支持本地协议转换，因此假设中间件层或端点满足任何此类要求。<br/></td>
    </tr>
    <tr>
        <td>翻译和转换</td>
        <td>转换是一种将数据格式映射到另一种格式的能力，以确保正在集成的各种系统之间的互操作性。通常，该过程需要重新格式化途中的消息，以匹配发件人或收件人的要求。在更复杂的情况下，一个应用程序可以发送其自己的本地格式的消息，两个或多个其他应用程序可以各自收到其本地格式的消息副本。<br/> <br/> 
            中间件翻译和转换工具通常包括为原有端点或其他非标准端点创建服务门面的功能。这些服务门面允许这些端点看起来是可服务寻址的。 <br/> <br/> 通过 Salesforce 集成，假设中间件层或端点满足任何此类要求。 数据转换可以在 Apex 中编码，但出于维护和性能考虑，我们不建议这样做。<br/> <br/> 
        </td>
      </tr>
      <tr>
        <td>排队和缓冲</td>
        <td>队列和缓冲通常依赖于异步消息传递，而不是请求-响应架构。在异步系统中，当目标程序繁忙或连接性受损时，消息队列会提供临时存储。此外，大多数异步中间件系统都提供持久存储来备份消息队列。<br/> <br/> 
            异步消息流程的关键好处是，如果接收方应用程序因任何原因失败，发送方可以不受影响地继续工作。发送的消息仅在消息队列中累积，以便稍后在接收器重新启动时处理。 <br/>  Salesforce 仅以基于工作流的出站消息传递的形式提供显式队列功能。要为其他集成场景（包括编排、流程编排和服务质量）提供真正的消息队列，需要一个中间件解决方案。<br/>
        </td>
      </tr>
      <tr>
        <td>同步传输协议</td>
        <td>同步传输协议是指支持以下活动的协议：“调用者中的单个线程发送请求消息，阻止等待回复消息，然后处理回复。...等待响应的请求线程意味着只有一个未完成的请求，或者该请求的回复渠道对该线程是专用的。”
        </td>
      </tr>
      <tr>
        <td>异步传输协议</td>
        <td>异步传输协议是指支持活动的协议，其中“调用者中的一个线程发送请求消息并为回复设置回调。一个单独的线程监听回复消息。当回复消息到达时，回复线程调用适当的回调，这会重新建立调用者的上下文并处理回复。这种方法允许多个未完成的请求共享一个回复线程。”                 
        </td>
      </tr>
      <tr>
        <td>中介路由</td>
        <td>中介路由是组件之间复杂消息“流”的规范。例如，许多基于中间件的解决方案依赖于消息队列系统。虽然一些实施允许消息传递层本身提供路由逻辑，但其他实施依赖于客户端应用程序来提供路由信息或允许两种范式的组合。在这种复杂的情况下，中间件的中介简化了开发、集成和验证。
        Ordinator [Mediator] 可以确保将正确的消息发送给正确的消费者。”           
        </td>
      </tr>
      <tr>
        <td>流程编排和服务编排</td>
        <td>流程编排和服务编排是每种形式的“服务组合”，其中协调了任意数量的端点和能力。
        <br/> <br/>  编舞和服务编排之间的区别是：
        <ul>
            <li>编舞可以定义为一种异步方法，它使流程能够自主地工作，消除了依赖关系造成的任何问题，依赖关系是一组没有中央权威的交互个人实体所产生的行为。</li>
            <li>编配可以定义为一种同步方法，它通过允许每个微服务实施编配器分配的任务来实现查询或流程的执行，该任务是由中央指挥员协调执行任务的各个实体的行为而产生的行为，这些实体彼此独立。</li>
        </ul>
        此外，编排会显示每个服务的完整行为，而编排会合并每个服务的界面行为描述。
        <br/>
        部分业务流程编排可以在 Salesforce 工作流中构建，也可以使用 Apex。由于 Salesforce 超时值和调控器限制，我们建议在中间件层实施所有复杂的编排，特别是在需要真正事务处理的解决方案中。                    
        </td>
      </tr>
      <tr>
        <td>事务性（加密、签名、可靠交付、事务管理）</td>
        <td>事务性可以定义为支持全局事务的能力，该事务包含针对每个所需资源的所有必要操作。事务性意味着支持所有 4 种 ACID 属性，原子性、一致性、隔离性、耐用性，其中原子性保证工作单位（事务）的“全有或全无”结果。
        <br/> <br/>虽然 Salesforce 本身是事务性的，但它不能参与分布式事务或在 Salesforce 之外发起的事务。因此，假设对于需要复杂、多系统事务的解决方案，事务性和关联的回滚/补偿机制在中间件层实施。<br/> 
        </td>
      </tr>
      <tr>
        <td>路由</td>
        <td>路由可以定义为指定组件之间的复杂消息流。在现代基于服务的解决方案中，此类消息流可以基于多个标准，包括标题、内容类型、规则和优先级。
            <br/> <br/>  通过 Salesforce 集成，假设中间件层或端点满足任何此类要求。消息路由可以在 Apex 中编码，但出于维护和性能考虑，我们不建议这样做。
       </td>
      </tr>
      <tr>
       <td>提取、转换和加载</td>
        <td>提取、转换和加载 (ETL) 是指涉及以下内容的过程：
           <ul>
                <li>从源系统提取数据。此流程通常涉及来自多个源系统的数据，以及关系和非关系结构。</li>
                <li>转换数据以适应业务需求，其中可以包括数据质量级别。转换阶段通常将一系列规则或函数应用于从源提取的数据，以导出数据并加载到最终目标。</li>
                <li>将数据加载到目标系统。目标系统因数据库、操作数据存储、数据集市、数据仓库或其他操作系统而异。</li>
            </ul>   
            虽然并非绝对必要，但大多数成熟的 ETL 工具都提供了变更数据捕获功能。该功能是工具识别源系统中自上次提取后发生变化的记录的地方，这减少了记录处理量。<br/> <br/> 
            Salesforce 现在还支持变更数据捕获，即发布变更事件，表示对 Salesforce 记录的变更。通过变更数据捕获，客户端或外部系统接收 Salesforce 记录的近乎实时的变更。通过此信息，客户端或外部系统可以同步外部数据存储中的相应记录。<br/> <br/>            
        </td>
      </tr>
      <tr>
       <td>长时间投票</td>
        <td>长轮询也称为 Comet 编程，它模拟从服务器到客户端的信息推送。与正常轮讯相似，客户端连接并向服务器请求信息。但如果信息不可用，服务器不会发送空响应，而是保留请求并等待，直到信息可用（事件发生）。然后，服务器向客户端发送完整的响应。然后，客户端立即重新请求信息。客户端持续保持与服务器的连接，因此它总是等待收到响应。如果服务器超时，客户端会重新连接并重新开始。<br/> <br/> 
            Salesforce 串流 API 使用 Bayeux 协议和 CometD 进行长轮询。
            <ul>
                <li>Bayeux 是一种主要通过 HTTP 传输异步消息的协议。</li>
                <li>CometD 是一种可扩展的基于 HTTP 的事件路由总线，它使用称为 Comet 的 AJAX 推送技术模式。它实施 Bayeux 协议。</li>
            </ul>       
        </td>
      </tr>
</table>

## 远程进程调用 — 请求和回复

**上下文**

您可以使用 Salesforce 跟踪潜在客户、管理漏斗、创建业务机会并捕获将潜在客户转换为客户的订单详细信息。但是，Salesforce 系统不包含或处理订单。在 Salesforce 中捕获订单详细信息后，将在远程系统中创建订单，远程系统管理订单直至完成。

当您实施此模式时，Salesforce 会调用远程系统来创建订单，然后等待成功完成。如果成功，远程系统会同步回复订单状态和订单号。作为相同交易的一部分，Salesforce 会在内部更新订单号和状态。订单号用作远程系统后续更新的外键。

**问题**

当 Salesforce 中发生事件时，您如何在远程系统中启动进程，向该进程传递所需的信息，从远程系统接收响应，然后使用该响应数据进行 Salesforce 中的更新？

**武力**

在应用基于此模式的解决方案时，请考虑以下力量。

- 对远程系统的调用是否需要 Salesforce 在继续处理之前等待响应？对远程系统的调用是同步请求-回复还是异步请求？
- 如果对远程系统的调用是同步的，Salesforce 是否需要将响应作为初始调用的相同事务的一部分进行处理？
- 消息大小是小还是大？
- 集成是基于特定事件的发生，例如 Salesforce 用户界面中的按钮单击，还是基于 DML 的事件？
- 远程端点是否能够以低延迟响应请求？在高峰期间，有多少用户可能会执行此事务？

**解决方案**

此表包含此集成问题的解决方案。

  <table>
    <tr>
      <th>解决方案</th>
      <th>适合</th>
      <th>评论</th>
    </tr>
    <tr>
      <td>外部服务调用 REST API 调用</td>
      <td>最佳</td>
      <td>外部服务允许您以声明方式调用外部托管的服务（无需代码）。此功能最好在满足以下条件时使用：
      <ul>
      <li>外部托管的服务是 RESTful 服务，定义以 OpenAPI 2.0、OpenAPI 3.0 或 YAML 模式格式提供。</li>
      <li>请求和响应定义包含原始数据类型，例如布尔值、日期时间、双精度、整数、字符串或原始数据类型数组。支持 HTTP 请求中的嵌套对象类型和发送参数，例如标题。</li>
      <li>事务可以从流中调用。</li>
      </ul>
      </td>
    </tr>
    <tr>
      <td>Salesforce Lightning — Lightning 组件或页面启动同步 Apex REST 或 SOAP 标注。&lt;/<br/> <br/> 如果远程端点存在高延迟响应的风险(请参阅此处的最新限制文档以了解适用限制 ) , 则建议使用异步标注，也称为继续，以避免达到同步 Apex 事务调控器限制。
      </td>
      <td>最佳</td>
      <td>Salesforce 使您能够使用 WSDL 并生成生成的代理 Apex 类。该类提供了调用远程服务的必要逻辑。<br/> <br/> 
      Salesforce 还允许您使用标准 GET、POST、PUT 和 DELETE 方法调用 HTTP (REST) 服务。<br/> <br/> 
      然后，Lightning 页面上的用户发起的操作调用 Apex 控制器操作，然后执行此代理 Apex 类来执行远程调用。Lightning 页面需要自定义 Salesforce 应用程序。
      </td>
    </tr>
    <tr>
      <td>从 Salesforce 数据更改调用的同步触发器执行异步 Apex SOAP 或 HTTP 标注。</td>
      <td>次优</td>
      <td>您可以使用 Apex 触发器根据记录数据更改执行自动化。<br/> <br/> 
      Apex 代理类可以作为 DML 操作的结果使用 Apex 触发器来执行。但是，从触发器上下文中发出的所有调用都必须从发起事件异步执行。因此，对于此集成问题，不建议使用此解决方案。此解决方案更适合远程进程调用 — 触发并忘记模式。
      </td>
    </tr>
    <tr>
      <td>批处理 Apex 作业执行同步 Apex SOAP 或 HTTP 标注。</td>
      <td>次优</td>
      <td>您可以从批处理作业调用远程系统。此解决方案允许在 Salesforce 中批量执行远程流程并处理来自远程系统的响应。但给定批次对呼叫次数有限制。有关更多信息，请查看<a href="https://developer.salesforce.com/docs/atlas.en-us.integration_patterns_and_practices.meta/integration_patterns_and_practices/integ_pat_remote_process_invocation_state.htm#governor_limits_header">州长限制。</a><br/> <br/> 
      给定的批处理运行可以执行多个事务上下文（通常以 200 条记录的时间间隔）。调控器限制会根据事务上下文重置。
      </td>
    </tr>
  </table>

**草图**

此图说明了使用 Apex 调用的同步远程过程调用。

**Salesforce 调用远程系统**

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Integration Patterns - RPI- Request and Reply.png" alt="Salesforce 调用远程系统">

<a href="https://a.sfdcstatic.com/developer-website/prod/assets/architect/pdf/integration-patterns/Integration Patterns - RPI- Request and Reply.pdf">下载图表</a><br/>

在这种情况下：

- 在 Lightning 页面上启动操作（例如，单击按钮）。
- 浏览器（在 Lightning 组件的情况下通过客户端控制器）执行 HTTP POST，该 POST 又在相应的 Apex 控制器上执行操作。
- 控制器调用对远程 Web 服务的实际调用。
- 来自远程系统的响应被返回到 Apex 控制器。控制器处理响应，根据需要更新 Salesforce 中的数据，并重新呈现页面。

在必须跟踪后续状态的情况下，远程系统会返回存储在 Salesforce 记录中的唯一标识符。

**结果**

应用与此模式相关的解决方案允许 Salesforce 处理事件发起的远程进程调用。

**调用机制**

调用机制取决于为实施此模式选择的解决方案。

<table>
<tr>
<th>调用机制</th>
<th>描述</th>
</tr>
<tr>
<td>嵌入到流或 <br/> <br/>  Lightning 组件或 <br/> <br/>  Apex 控制器
</td>
<td>当远程进程作为涉及用户界面的端到端进程的一部分被触发时，并且结果必须在 Salesforce 记录中显示或更新时使用。例如，向外部付款网关提交信用卡付款，付款结果会立即返回并显示给用户。</td>
</tr>
<tr>
<td>Apex 触发器
</td>
<td>主要用于使用 Apex 标注从 DML 发起的事件调用远程进程。有关此调用机制的更多信息，请查看模式 <a href="#远程进程调用--触发并忘记">远程进程调用 — 触发并忘记。</a></td>
</tr>
<tr>
<td>Apex 批处理类
</td>
<td>用于批量调用远程进程。有关此调用机制的更多信息，请查看模式 <a href="#远程进程调用--触发并忘记">远程进程调用 — 触发并忘记。</a></td>
</tr>
</table>

**错误处理和恢复**

将错误处理和恢复策略作为整体解决方案的一部分非常重要。

- 错误处理 - 当发生错误（异常或错误代码返回到调用方）时，调用方管理错误处理。例如，显示在最终用户页面上或记录在需要进一步操作的表中的错误消息。

- 恢复 — 更改不会提交到 Salesforce，直到呼叫者收到成功的响应。例如，在收到表示成功的响应之前，订单状态不会在数据库中更新。如有必要，呼叫者可以重试该操作。

**幂等设计注意事项**

幂等功能保证重复调用是安全的。如果未实施幂等性，重复调用同一消息会产生不同的结果，并可能导致数据完整性问题。潜在问题包括创建重复记录或重复处理事务。

重要的是要确保调用的远程过程幂等。如果通过用户界面进行调用，我们需要处理集成层中的嵌入问题，特别是如果不能保证 Salesforce 只调用一次。

构建幂等接收器的最典型方法是，根据消费者发送的唯一消息标识符跟踪重复项。Apex Web 服务或 REST 调用必须自定义，才能发送唯一的消息 ID。

此外，在远程系统中创建记录的操作必须在插入前检查重复项。通过从 Salesforce 传递唯一记录 ID 进行检查。如果记录存在于远程系统中，请更新记录。在大多数系统中，此操作称为更新插入操作。

**安全注意事项**

对远程系统的任何调用必须保持请求的机密性、完整性和可用性。以下安全注意事项特定于在此模式中使用 Apex SOAP 和 HTTP 调用。

- 默认情况下启用单向 SSL，但自签名和 CA 签名证书都支持双向 SSL，以保持客户端和服务器的真实性。

- 要简化 Apex 代码并简化经过身份验证的标注的设置，请在标注端点中指定命名凭据。

- 考虑使用 OAUTH 2.0 作为与外部系统集成的身份验证机制。

- 必要时，考虑使用 Apex Crypto 类方法使用单向哈希或数字签名，以确保请求完整性。

- 必须通过实施适当的防火墙机制来保护远程系统。请参阅[安全注意事项](#附录-b安全注意事项)。

- Salesforce 目前不支持 WS-Security。虽然它不会本地生成这些复杂的 WS-Security 标题或从传入 WSDL 自动强制执行它们，但您可以通过创建自定义 Apex 类来处理传入请求的 SOAP 标题和安全令牌来手动构建和实施它们。

**侧栏**

无。

**及时性**

及时性在这种模式中非常重要。通常：

- 通常从用户界面调用请求，因此进程不得让用户等待。
- Salesforce 对来自 Apex 的呼叫有最多 120 秒的可配置超时。
- 远程流程的完成会及时执行，以在 Salesforce 超时限制内并在用户预期内完成。
- 外部调用受 Apex 同步事务调控器限制，因此请确保降低实例化超过 50 个事务（每个事务运行时间超过 5 秒）的风险。除了确保外部端点的性能之外，减轻超时风险的选项包括：
  - 将外部标注的超时设置为五秒。
  - 在 Lightning 组件中使用延续来处理长时间运行的事务

**数据量**

由于 Apex 调用解决方案的请求或响应的超时值和最大大小较小，此模式主要用于小容量实时活动。请勿在消息中包含数据负载的批处理活动中使用此模式。

**端点功能和标准支持**

端点的功能和标准支持取决于您选择的解决方案。

<table>
<tr>
    <th>解决方案</th>
    <th>端点注意事项</th>
  </tr>
  <tr>
    <td>Apex HTTP 标注</td>
    <td>端点必须能够接收 HTTP 调用。Salesforce 必须能够通过公共互联网访问端点。对于专用和安全通信，Salesforce 现在也开始通过 Hyperforce 平台安全地支持 Salesforce 专用连接。有关更多详细信息，请查看 <a href="https://help.salesforce.com/s/articleView?id=sf.private_connect_overview.htm&type=5">Salesforce 专用连接</a>。
    <br/> <br/> 
    您可以使用 Apex HTTP 标注，以使用标准 GET、POST、PUT、DELETE 和 PATCH 方法调用 REST 服务。
    </td>
  </tr>
  <tr>
    <td>Apex SOAP 标注</td>
    <td>端点必须能够接收 HTTP 调用。Salesforce 必须能够通过公共互联网访问端点。对于专用和安全通信，Salesforce 现在也开始通过 Hyperforce 平台安全地支持 Salesforce 专用连接。有关更多详细信息，请查看 <a href="https://help.salesforce.com/s/articleView?id=sf.private_connect_overview.htm&type=5">Salesforce 专用连接</a>。
    <br/> <br/> 
    此解决方案要求远程系统兼容 Salesforce 支持的标准。在撰写本报告时，Salesforce 为 Apex SOAP 标注支持的 Web 服务标准是：
    <ul>
    <li>WSDL 1.1</li>
    <li>SOAP 1.1 </li>
    <li>WSI 基本简档 1.1</li>
    </ul>
    </td>
  </tr>
</table>

**状态管理**

在集成系统时，密钥对于正在进行的状态跟踪非常重要。有两种选择。

<ul>
<li>Salesforce 存储远程记录的主或唯一代理密钥。</li>
<li>远程系统存储 Salesforce 唯一记录 ID 或其他一些唯一代理密钥。</li>
</ul>

处理集成密钥时有一些特定的注意事项，具体取决于哪个系统包含主记录，如下表所示。

<table>
  <tr>
    <th>师父</th>
    <th>系统	描述</th>
  </tr>
  <tr>
    <td>Salesforce</td>
    <td>远程系统存储 Salesforce RecordId 或记录中的其他唯一替代密钥。</td>
  </tr>
   <tr>
    <td>远程系统</td>
    <td>对远程进程的调用会从应用程序中返回唯一密钥，Salesforce 将该密钥值存储在唯一记录字段中。</td>
  </tr>
</table>

**复杂集成场景**

在某些情况下，此模式规定的解决方案可能需要实施几个复杂的集成场景。最好使用中间件或让 Salesforce 调用复合服务。这些情况包括：

<ul>
  <li>业务流程和规则的编排涉及复杂的流逻辑</li>
  <li>对多个系统的呼叫及其结果的聚合</li>
  <li>入站和出站消息的转换</li>
  <li>保持对多个系统的调用之间的事务完整性</li>
</ul>

**州长限制**

有关 Apex 限制的信息，请参见 Apex 开发人员指南中的<a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm">_执行调控器和限制_</a>。

**中间件功能**

下表强调了参与此模式的中间件系统的理想属性。

<table>
  <tr>
    <th>房地产</th>
    <th>强制</th>
    <th>理想</th>
    <th>不需要</th>
  </tr>
  <tr>
    <td>事件处理</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
    <tr>
    <td>协议转换</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
    <tr>
    <td>翻译和转换</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>排队和缓冲</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>同步传输协议</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>异步传输协议</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
  <tr>
    <td>中介路由</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>流程编排和服务编排</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>事务性（加密、签名、可靠交付、事务管理）</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>路由</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
  <tr>
    <td>提取、转换和加载</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
  <tr>
    <td>长时间轮讯</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
</table>

**示例**

公用事业公司使用 Salesforce，并拥有包含客户计费信息的单独系统。作为订购流程的一部分，必须在开单系统中创建新开单客户，Salesforce 应在订单激活流程中反映开单客户编号。他们有一个现有的 Web 服务，允许创建开单帐户，并将开单帐户编号作为响应返回。

可通过以下方法完成此要求。

<ol>
  <li>Salesforce 使用 Apex 代理类中的计费帐户服务 WSDL。</li>
  <li>使用从自定义 Apex 控制器或外部服务传递到外部 Web 服务的客户信息，执行 Apex 代理类。</li>
  <li>然后，自定义控制器解析来自 Apex 标注的返回值，并将该信息存储在 salesforce 对象上。</li>
</ol>

此示例演示：

<ul>
  <li>使用存储在 Salesforce 客户对象上的客户编号跟踪客户的状态。</li>
  <li>呼叫者随后对回复消息的处理</li>
</ul>

## 远程进程调用 — 触发并忘记

**上下文**

您可以使用 Salesforce 跟踪潜在客户、管理漏斗、创建业务机会并捕获将潜在客户转换为客户的订单详细信息。但是，作为订单管理流程的一部分，需要在订单的计费系统中创建计费帐户。

当您实施此模式时，Salesforce 会调用远程系统来创建计费帐户，但不会等待调用的成功完成。远程系统可以选择使用在单独事务中创建的新计费帐户更新 Salesforce。

**问题**

当 Salesforce 中发生事件时，您如何在远程系统中启动进程，并将所需信息传递给该进程，而无需等待远程系统的响应？

**武力**

在应用基于此模式的解决方案时，请考虑以下力量。

<ul>
<li>对远程系统的调用是否需要 Salesforce 在继续处理之前等待响应？对远程系统的调用是同步的还是异步的？</li>
<li>如果对远程系统的调用是同步的，响应是否需要由 Salesforce 作为与调用相同的事务的一部分来处理？</li>
<li>消息大小是否小？</li>
<li>集成是基于特定事件的发生，例如 Salesforce 用户界面中的按钮单击，还是基于 DML 的事件？</li>
<li>是否要求保证消息从 Salesforce 传递到远程系统？</li>
<li>远程系统是否能够参与 Salesforce 指定合同的合同优先集成？在一些解决方案变体中（例如，出站消息传递），Salesforce 指定了远程系统端点实施的合同。</li>
<li>端点或企业服务总线 (ESB) 是否支持长轮询？</li>
<li>声明性配置方法是否优先于自定义 Apex 开发？在这种情况下，平台事件等解决方案优先于 Apex 标注。</li>
</ul>

**解决方案**

下表包含此集成问题的解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>适合</th>
    <th>评论</th>
  </tr>
  <tr>
    <td>流驱动的平台事件</td>
    <td>最佳</td>
    <td>以声明方式创建流，以实施平台事件。推荐的解决方案是在从插入或更新事件中调用远程进程时。<br/> <br/> 
    平台事件是应用程序发送和接收以采取进一步行动的事件消息（或通知）。平台事件简化了传达变更和响应变更的过程，而无需编写复杂的逻辑。一个或多个订阅者可以收听相同的事件并执行操作。<br/> <br/> 
    例如，软件系统可以发送包含打印机墨盒相关信息的事件。订阅者可以订阅事件来监控打印机的墨盒水平，并下订单更换墨盒水平较低的墨盒。<br/> <br/> 
    外部应用程序可以通过 CometD 订阅渠道来收听事件消息。Lightning 组件等平台应用程序也可以使用 CometD 订阅事件消息。也可以在此处使用基于 gRPC 和 HTTP/2 的 Salesforce PubSub Api。<br/> <br/> 
    Salesforce 还支持平台事件触发的流，这有效地允许使用 Flow Builder 界面创建监听程序。当特定的平台事件消息发布到 Salesforce 事件总线时，这种类型的流会自动启动。
    </td>
  </tr>
  <tr>
    <td>发布/订阅 API</td>
    <td>最佳</td>
    <td>发布/订阅 API 是外部消费者在事件总线上使用事件的推荐方式。<br/> <br/> 
    基于 gRPC 的发布/订阅 API： 
    <ul>
    <li>支持从外部应用程序发布和订阅平台事件</li>
    <li>通过正确身份验证可用（OAuth、JWT 或会话令牌）</li>
    </ul>
    <br/>
    在 Salesforce 中定义平台事件后，内部和外部消费者都可以使用它。
    </td>
  </tr>
  <tr>
    <td>变更数据捕获</td>
    <td>最佳</td>
    <td>变更数据捕获 (CDC) 发布 Salesforce 记录中与创建、更新、删除和取消删除操作对应的变更事件。在 Salesforce 中启用变更数据捕获 (CDC) 是一个纯粹的声明性过程，不需要 Apex 代码。<br/> <br/>  
    通知消息被发送到客户端可以使用发布/订阅 API 或 Apex 触发器订阅的事件总线。事件驱动的系统简化了分布式企业系统之间的通信，提高了可扩展性，并提供了实时数据。<br/> <br/> 
    例如，如果订单信息同时驻留在 ERP 系统和 Salesforce 中，您可以将订单变更事件从 Salesforce 流式传输到集成应用程序。然后，该应用程序会同步 ERP 系统中的更改</td>
  </tr>
  <tr>
    <td>Omnistudio 集成程序</td>
    <td>好</td>
    <td>使用 Omnistudio 集成程序，以声明性方式自动化 Salesforce 与外部第三方应用程序之间的数据交互。集成程序处理复杂的数据转换、API 调用和事件驱动的自动化，它们可以在单个服务器调用中执行多个操作。<br/> <br/> 
    在执行过程中不需要用户交互，并且您想要：
    <ul>
      <li>在 Salesforce 和外部系统之间检索、转换和发送数据</li>
      <li>将处理卸载到服务器，以提高性能和可扩展性</li>
      <li>在单个服务器事务中捆绑多个操作</li>
      <li>为频繁访问的信息启用数据缓存</li>
    </ul>
    <br/> 
    查看有关集成程序的更多详细信息<a href="https://help.salesforce.com/s/articleView?id=xcloud.os_omnistudio_integration_procedures_48334.htm&type=5">。</a>
    </td>
  </tr>
  <tr>
    <td>自定义驱动的平台事件</td>
    <td>好</td>
    <td>与流驱动的平台事件相似，但事件由 Apex 触发器或类创建。您可以使用 Apex 或 API 发布和使用平台事件。<br/> <br/> 
    平台事件通过 Apex 触发器与 Salesforce 平台集成。触发器是 Salesforce 平台上监听事件消息的事件使用者。<br/> <br/> 
    当外部应用程序使用 API 或本地 Salesforce 应用程序使用 Apex 发布事件消息时，将触发该事件的触发器。触发器运行操作以响应事件通知。
    </td>
  </tr>
  <tr>
    <td>流驱动的出站消息传递</td>
    <td>适合</td>
    <td>对于这种类型的集成，推荐的解决方案是在从插入或更新事件中调用远程进程时。Salesforce 提供流驱动的出站消息传递功能，允许向由 Salesforce 中的插入或更新操作触发的远程系统发送 SOAP 消息。这些消息异步发送，并且独立于 Salesforce 用户界面。<br/> <br/> 
    出站消息被发送到特定的远程端点。远程服务必须能够参与 Salesforce 提供合同的合同优先集成。<br/> <br/> 
    收到消息后，如果远程服务没有以积极确认的方式响应，Salesforce 会尝试发送消息，并提供某种形式的保证交付。
    </td>
  </tr>
    <tr>
    <td>启动 Apex SOAP 或 HTTP 异步标注的自定义 Lightning 组件</td>
    <td>次优</td>
    <td>此解决方案通常用于基于用户界面的场景，但的确需要自定义。此外，解决方案必须在代码中处理消息的保证传递。<br/> <br/> 
    与<a href="#远程进程调用--请求和回复">远程过程调用</a>请求和回复模式解决方案相似,该解决方案指定使用 Lightning 组件和 Apex 标注。不同的是，在这种模式中，Salesforce 不会等待请求完成，然后再将控制移交给用户。<br/> <br/> 
    收到消息后，远程系统响应并表示收到消息，然后异步处理消息。远程系统在开始处理消息之前将控制权限交还给 Salesforce；因此，Salesforce 无需等待处理完成。
    </td>
  </tr>
  <tr>
    <td>Apex 触发器进行 Apex SOAP 或 HTTP 异步标注</td>
    <td>次优</td>
    <td>您可以使用 Apex 触发器根据记录数据更改执行自动化。<br/> <br/> 
    Apex 代理类可以作为 DML 操作的结果使用 Apex 触发器来执行。但是，从触发器上下文中进行的所有调用都必须异步执行。
    <br/> <br/> 
    </td>
  </tr>
    <tr>
    <td>Apex 触发器进行 Apex SOAP 或 HTTP 异步标注</td>
    <td>次优</td>
    <td>可以从批处理作业中执行对远程系统的调用。此解决方案允许在 Salesforce 中批量执行远程流程并处理来自远程系统的响应。但是，给定批处理上下文的调用次数是有限制的。有关更多信息，请查看 <a href="https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_overview.htm">Salesforce 开发人员限制和分配快速参考</a>。
    <br/> <br/> 
    </td>
  </tr>
</table>

**草图**

下图说明了从 Salesforce 到远程系统的调用，其中对记录的创建或更新操作会触发调用。

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Integration Patterns - Fire and Forget.png" alt="Salesforce 调用远程系统">

<a href="https://a.sfdcstatic.com/developer-website/prod/assets/architect/pdf/integration-patterns/Integration Patterns - Fire and Forget.pdf">下载图表</a><br />

在这种情况下：

<ol>
<li>远程系统订阅平台事件。</li>
<li>在 Salesforce 中，对一组给定的记录进行更新或插入。</li>
<li>Salesforce 流会在满足一组条件时触发。</li>
<li>此流创建平台事件。</li>
<li>远程监听程序接收事件消息，并将消息放在本地队列中。</li>
<li>排队应用程序将消息转发到远程应用程序进行处理。</li>
</ol>

在远程系统必须对 Salesforce 执行操作的情况下，您可以实施可选回调操作。

**结果**

应用与此模式相关的解决方案允许：

<ul>
<li>用户界面 - 发起的远程进程调用，其中事务的结果可以向最终用户显示</li>
<li>DML 事件发起的远程进程调用，其中事务的结果可以由调用进程处理</li>
</ul>

**调用机制**

调用机制取决于为实施此模式选择的解决方案。

<table>
<tr>
<th>调用机制</th>
<th>描述</th>
</tr>
<tr>
<td>流</td>
<td>由流程驱动和自定义驱动的解决方案使用。事件触发 Salesforce 流程，然后该流程可以发布平台事件，供远程系统订阅。</td>
</tr>
<tr>
<td>Pub / Sub API</td>
<td>发布/订阅 API 提供了用于发布和订阅平台事件的单一界面，包括实时事件监控事件和变更数据捕获事件。基于 gRPC 和 HTTP/2，发布/订阅 API 以 Apache Avro 格式高效地发布和传递二进制事件消息。</td>
</tr>
<tr>
<td>变更数据捕获</td>
<td>Salesforce 变更数据捕获发布变更事件，表示对 Salesforce 记录的变更。更改包括创建新记录、更新现有记录、删除记录和取消删除记录。</td>
</tr>
<tr>
<td>Lightning 组件和 Apex 控制器</td>
<td>用于使用 Apex 标注异步调用远程进程。</td>
</tr>
<tr>
<td>流驱动的出站消息传递</td>
<td>仅用于出站消息传递解决方案。创建和更新 DML 事件会触发 Salesforce 工作流规则，然后工作流规则会向远程系统发送消息。</td>
</tr>
<tr>
<td>Apex 触发器</td>
<td>使用来自 DML 发起事件的 Apex 标注，用于触发器驱动的平台事件和远程进程的调用。</td>
</tr>
<tr>
<td>Apex 批处理类</td>
<td>用于在批处理模式中调用远程进程。</td>
</tr>
</table>

**错误处理和恢复**

必须将错误处理和恢复策略视为整体解决方案的一部分。最佳方法取决于您选择的解决方案。

<table>
<tr>
  <th>解决方案</th>
  <th>错误处理和恢复策略</th>
</tr>
<tr>
  <td>流</td>
  <td>
  <ul>
    <li>错误处理 — 在某些情况下，流可能无法完全处理。在流程或流采访失败时，将向上次修改流程或流的管理员发送一封详细的电子邮件。通过向所有可能失败的元素添加错误路径来修改默认行为。应该增强这种行为，以引入自定义行为，例如创建个案或将错误写入可以监控和跟踪的自定义对象。</li>
    <li>恢复 — 在这种情况下，恢复更加复杂。如果服务质量要求，必须创建自定义重试机制。</li>
  </ul>
  </td>
</tr>
<tr>
  <td>Apex 标注</td>
  <td>
  <ul>
    <li>错误处理 — 远程系统会放弃对结束进程的调用，因此标注仅在远程服务的初始调用中处理异常。例如，如果未从远程标注收到正面确认，则会触发超时事件。当初始调用被切换到异步处理时，远程系统必须处理后续错误。</li>
    <li>恢复 — 在这种情况下，恢复更加复杂。如果服务质量要求，必须创建自定义重试机制。</li>
  </ul>
  </td>
</tr>
<tr>
  <td>变更数据捕获 (CDC)/平台事件</td>
  <td>
  <ul>
    <li>错误处理 — 必须由远程服务执行错误处理，因为事件有效地移交给远程系统作进一步处理。由于此模式异步，远程系统会处理消息队列、处理和错误处理。此外，平台事件不会在数据库事务中处理。因此，已发布的平台事件无法在事务中回滚。</li>
    <li>恢复 — 由于此模式异步，远程系统必须根据服务质量要求启动重试。与每个事件关联的重放 ID 是原子性的，并随着每个发布的事件而增加。此 ID 可用于从特定事件重放流（例如，基于上次成功捕获的事件）。高用量平台事件消息存储 72 小时（三天）。在使用 CometD 客户端订阅渠道时，您可以检索过去的事件消息。</li>
  </ul>
  </td>
</tr>
</table>

**幂等设计注意事项**

平台事件仅发布到总线一次。Salesforce 侧没有重试。由 ESB 请求重放事件。在重放中，平台事件的重放 ID 保持不变，ESB 可以根据重放 ID 尝试重复消息。

冗余性对于出站消息传递非常重要，因为它是异步的，当没有收到正面确认时就会启动重试。因此，远程服务必须能够以幂等的方式处理来自 Salesforce 的消息。

出站消息传递会为每个消息发送一个唯一的 ID，对于任何重试，此 ID 保持不变。远程系统可以根据此唯一 ID 跟踪重复消息。此外，也会发送每个正在更新的记录的唯一记录 ID，并可用于防止重复创建记录。

远程进程调用 — 请求和回复模式中的<a href="#远程进程调用--请求和回复">幂等设计考虑</a>因素也适用于此模式。

**安全注意事项**

对远程系统的任何调用必须保持请求的机密性、完整性和可用性。不同的安全注意事项适用，这取决于您选择的解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>安全注意事项</th>
  </tr>
  <tr>
    <td>Apex 标注</td>
    <td>对远程系统的调用必须保持请求的机密性、完整性和可用性。以下是特定于在此模式中使用 Apex SOAP 和 HTTP 调用的安全注意事项。
    <ul>
      <li>默认情况下启用单向 SSL，但自签名和 CA 签名证书都支持双向 SSL，以保持客户端和服务器的真实性。</li>
      <li>Salesforce 在生成 Apex 代理类时不支持 WS-Security。</li>
      <li>必要时，考虑使用 Apex Crypto 类方法使用单向哈希或数字签名，以确保请求的完整性。</li>
      <li>必须通过实施适当的防火墙机制来保护远程系统。</li>
    </ul>
    </td>
  </tr>
    <tr>
    <td>变更数据捕获 (CDC)/平台事件</td>
    <td>对于平台事件，订阅的外部系统必须能够对 Salesforce 串流 API 进行身份验证。<br/> <br/> 
    平台事件符合 Salesforce 组织中配置的现有安全模型。要订阅事件，用户需要对事件实体的读取权限。要发布事件，用户需要对事件实体拥有“创建”权限。
    </td>
  </tr>
</table>

请参阅<a href="#附录-b安全注意事项">安全注意事项。</a>

**侧栏**

无。

**及时性**

及时性是火灾和被遗忘的模式不太重要的因素。控制会立即或在确认成功切换到远程系统后交还给客户端。使用 Salesforce 出站消息传递，确认必须在 24 小时内发生（可以延长至 7 天）；否则，消息过期。对于平台事件，Salesforce 会将事件发送到事件总线，无需等待订阅者的确认或确认。如果订阅者未接收消息，订阅者可以使用事件回复 ID 请求重放事件。高用量事件消息存储 72 小时（三天）。要检索过去的事件消息，请使用 CometD 客户端订阅渠道。

**数据量**

数据量注意事项取决于您选择的解决方案。有关每个解决方案的限制，请参阅<a href="https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_overview.htm">Salesforce 限制快速参考。</a>

**端点功能和标准支持**

端点的功能和标准支持取决于您选择的解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>端点注意事项</th>
  </tr>
  <tr>
    <td>Apex SOAP 标注</td>
    <td>端点必须能够通过 HTTP 处理 Web 服务调用。Salesforce 必须能够通过公共互联网访问端点。此解决方案要求远程系统兼容 Salesforce 支持的标准。在撰写本报告时，Salesforce 为 Apex SOAP 标注支持的 Web 服务标准是：
    <ul>
      <li>WSDL 1.1</li>
      <li>SOAP 1.1</li>
      <li>WSI 基本简档 1.1</li>
      <li>HTTP</li>
    </ul>   
    </td>
  </tr>
  <tr>
    <td>Apex HTTP 标注</td>
    <td>端点必须能够接收 HTTP 调用，并且可由 Salesforce 通过公共互联网访问。<br/> <br/> Apex HTTP 标注可用于使用标准 GET、POST、PUT 和 DELETE 方法调用 RESTful 服务。
  </td>
  </tr>
  <tr>
    <td>变更数据捕获 (CDC)/平台事件</td>
    <td>
    <ul>
      <li>触发器、进程和流可以订阅事件。您可以收到事件通知，而不管它们是如何发布的。</li>
      <li>使用 CometD 从外部客户端订阅平台事件。实施您自己的 CometD 客户端或使用 EMP 连接器，这是一个开源、社区支持的工具，可以实施连接到 CometD 并在频道上监听的所有细节。Salesforce 按照接收顺序将平台事件发送到 CometD 客户端。事件通知的顺序取决于事件的重放 ID。</li>
    </ul>
    </td>
  </tr>
</table>

**状态管理**

在集成系统时，唯一的记录标识符对于正在进行的状态跟踪非常重要。例如，如果在远程系统中创建记录，您有两个选项。

<ul>
  <li>Salesforce 存储远程记录的主或唯一代理密钥。</li>
  <li>远程系统存储 Salesforce 唯一记录 ID 或其他一些唯一代理密钥。</li>
</ul>

下表列出了此模式中状态管理的注意事项。

<table>
  <tr>
    <th>师父</th>
    <th>系统	描述</th>
  </tr>
  <tr>
    <td>Salesforce</td>
    <td>远程系统必须在 Salesforce 记录中存储 Salesforce RecordId 或其他一些唯一的替代密钥。</td>
  </tr>
  <tr>
    <td>远程系统</td>
    <td>Salesforce 必须在远程系统中存储对唯一标识符的引用。由于进程异步，存储此唯一标识符不能成为原始事务的一部分。<br/> <br/> 
    Salesforce 必须在对远程进程的调用中提供唯一 ID。然后，远程系统必须回调 Salesforce，以使用 Salesforce 唯一 ID 使用远程系统的唯一标识符更新 Salesforce 中的记录。<br/> <br/> 
    回调意味着远程应用程序中的特定状态处理，以存储该事务的 Salesforce 唯一标识符，以便在处理完成时用于回调，或者 Salesforce 唯一标识符存储在远程系统的记录上。</td>
  </tr>
</table>

**复杂集成场景**

对于复杂的集成场景，例如转换和流程编排，此模式中的每个解决方案都有不同的注意事项。

<table>
<tr>
  <th>解决方案</th>
  <th>注意事项</th>
</tr>
<tr>
  <td>Apex 标注</td>
  <td>在某些情况下，此模式规定的解决方案需要实施几个复杂的集成场景，最好使用中间件或让 Salesforce 调用复合服务。这些情况包括：
  <ul>
    <li>业务流程和规则的编排涉及复杂的流逻辑</li>
    <li>对多个系统的呼叫及其结果的聚合</li>
    <li>入站和出站消息的转换</li>
    <li>保持对多个系统的调用之间的事务完整性</li>
  </ul>
</td>
</tr>
<tr>
  <td>变更数据捕获 (CDC)/平台事件</td>
  <td>鉴于事件的静态声明性质，无法在 Salesforce 中执行复杂的集成场景，例如聚合、编排或转换。远程系统或中间件必须处理这些类型的操作。</td>
</tr>
<tr>
  <td>OmniStudio 集成程序</td>
  <td>集成程序 (OmniStudio) 提供服务器端的无状态编排，以便在执行复杂的声明性数据转换时协调多个后端服务。<br/> <br/> 
  集成程序链步骤，例如 HTTP 操作、DataRaptor 提取/转换/加载、设置值、循环/如果和矩阵查找，以在 UI 合同和不同 API 之间标准化、丰富、聚合和映射负载。<br/> <br/> 
  它们支持强大的运行时控制，例如条件分支、分页、超时、重试、部分故障处理和继续出错，以及性能优化，例如服务器端缓存和响应整形。<br/> <br/> 
  IP 可以从 OmniScript 同步调用，也可以通过 REST 无头调用，从而实现可重用的版本化“集成外观”，对渠道隐藏后端复杂性。 
  </td>
</tr>
</table>

**州长限制**

由于 Salesforce 平台的多租户性质，出站标注存在限制。限制取决于出站呼叫的类型和呼叫的时间。

有关适用于平台事件的限制和分配，请参阅<a href="https://developer.salesforce.com/docs/atlas.en-us.256.0.platform_events.meta/platform_events/platform_events_intro.htm">平台事件开发人员指南</a>。

**可靠消息传递**

可靠的消息传递尝试解决保证将消息传递到单个组件不可靠的远程系统的问题。确保远程系统收到消息的方法取决于您选择的解决方案。

在 Salesforce 变更的情况下，提供变更事件的数据捕获类型来处理特殊情况，例如捕获未在 Salesforce 应用程序服务器中捕获的变更，或处理大量变更。

在某些情况下，Salesforce 会发送差距事件，而不是变更事件，以通知订阅者错误，或者如果无法生成变更事件。间隙事件包含有关标题更改的信息，例如更改类型和记录 ID。它不包括有关更改的详细信息，例如记录字段。为了更有效地捕获更改，将为超过阈值的单个事务生成溢出事件。有关更多信息，请查看<a href="https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_other_events.htm">此处</a>。

<table>
  <tr>
    <th>解决方案</th>
    <th>可靠的消息传递注意事项</th>
  </tr>
  <tr>
    <td>Apex 标注</td>
    <td>Salesforce 不提供对可靠消息传递协议的明确支持（例如，WS-ReliableMessaging）。我们建议接收 Salesforce 消息的远程端点实施可靠的消息传递系统，例如 JMS 或 MQ。此系统确保完全端到端地保证传递到最终处理消息的远程系统。但是，该系统不能保证从 Salesforce 传递到它调用的远程端点。<br/> <br/> 
    必须通过对 Salesforce 的自定义来处理保证交付。除了自定义重试逻辑之外，还必须实施特定的技术，例如处理来自远程端点的积极确认。</td>
  </tr>
  <tr>
    <td>变更数据捕获 (CDC)/平台事件</td>
    <td>平台事件尝试通过在事件总线中临时保留事件消息来提供可靠的消息传递。通过使用事件消息的重放 ID 重放事件总线中的消息，订阅者可以追赶错过的事件消息。<br/> <br/> 
    事件总线是分布式系统，没有事务数据库的相同保证。因此，Salesforce 无法为事件发布请求提供同步响应。事件被排队和缓冲，Salesforce 尝试异步发布事件。在极少数情况下，事件消息可能不会在初始或后续尝试期间保留在分布式系统中。这意味着事件不会交付给订阅者，并且不可恢复。</td>
  </tr>
  <tr>
  </tr>
</table>

**中间件功能**

下表强调了参与此模式的中间件系统的理想属性。

<table>
    <tr>
      <th>房地产</th>
      <th>强制</th>
      <th>理想</th>
      <th>不需要</th>
    </tr>
    <tr>
      <td>事件处理</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>协议转换</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>翻译和转换</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>排队和缓冲</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>同步传输协议</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>异步传输协议</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>中介路由</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>流程编排和服务编排</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>事务性（加密、签名、可靠交付、事务管理）</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>路由</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>提取、转换和加载</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>长时间轮讯</td>
      <td align="center">X（平台事件必填）</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
  </table>

**解决方案变体 — 平台事件：发布行为和事务**

当平台事件消息立即发布时，事件发布不会遵守发布流程的事务边界。事件消息可以在事务完成之前发布，或者即使事务失败。当订阅者期望找到发布事务提交的数据时，这种行为会导致问题。订阅者收到事件消息时，数据可能不存在。要解决此问题，请在事件定义中将平台事件发布行为设置为提交后发布。您可以在平台事件定义中设置的发布行为包括：

<ul>
  <li>提交后发布，以便仅在事务成功提交后发布事件消息。如果订阅者依赖于发布事务提交的数据，请选择此选项。例如，进程发布事件消息并创建任务记录。触发订阅事件的第二个进程，并期望找到任务记录。选择此行为的另一个原因是，如果事务失败，您不希望发布事件消息。</li>
  <li>立即发布，以便在执行发布调用时发布事件消息。如果您希望发布事件消息，而不管事务是否成功，请选择此选项。如果发布者和订阅者是独立的，并且订阅者不依赖于发布者提交的数据，也可以选择此选项。例如，即时发布行为适用于用于记录目的的事件。使用此选项，订阅者可能会在发布者事务提交数据之前收到事件消息。</li>
</ul>

**示例**

一家电信公司希望将 Salesforce 用作前端，以使用潜在客户到业务机会流程创建客户。当业务机会结束并赢得时，将在 Salesforce 中创建订单，但后端 ERP 系统是数据主系统。订单必须保存到 Salesforce 业务机会记录，并且业务机会状态已更改，以表示订单已创建。

以下约束适用。

<ul>
  <li>只能实施声明性开发。</li>
  <li>在业务机会转换为订单后，您不需要立即通知订单号。</li>
  <li>该组织有一个支持 CometD 协议的 ESB，能够订阅平台事件。</li>
</ul>

此示例最好使用 Salesforce 平台事件实施，但的确需要 ESB 订阅平台事件。

在 Salesforce 方面：

<ul>
  <li>创建流来启动平台事件（例如，当业务机会状态更改为“已结束并赢得客户”时）。</li>
  <li>创建一个发布业务机会详细信息的新平台事件。</li>
</ul>

在远程系统侧：

<ul>
<li>ESB 使用 CometD 协议订阅 Salesforce 平台事件。</li>
<li>ESB 会收到一个或多个通知，指示业务机会要转换为订单。</li>
<li>ESB 将消息转发到后端 ERP 系统，以便创建订单。</li>
<li>在 ERP 系统中创建订单后，一个单独的线程会使用 SessionId 作为身份验证令牌回调到 Salesforce。回调会使用订单号和状态更新业务机会。您可以使用文档化的模式解决方案执行此回调，例如 Salesforce 平台事件、Salesforce SOAP API、REST API 或 Apex Web 服务。</li>
</ul>

此示例演示以下内容。

<ul>
  <li>异步调用远程进程的实施</li>
  <li>端到端保证交付</li>
  <li>随后回调到 Salesforce，以更新记录的状态</li>
</ul>

## Batch Data Synchronization

**上下文**

您将 CRM 实施转移到 Salesforce，并想要：

<ul>
  <li>从当前 CRM 系统中提取和转换客户、联系人和业务机会，并将数据加载到 Salesforce（初始数据导入）。</li>
  <li>每周（持续）从远程系统提取、转换客户计费数据并将其加载到 Salesforce。</li>
  <li>从 Salesforce 中提取客户活动信息，并每周（持续）将其导入内部数据仓库。</li>
</ul>

**问题**

考虑到这些导入和导出会干扰工作时间的最终用户操作，并涉及大量数据，您如何将数据导入 Salesforce 并将数据导出 Salesforce？

**武力**

在应用基于此模式的解决方案时，需要考虑各种因素：

<ul>
<li>数据是否应存储在 Salesforce 中？如果没有，架构师可以而且应该考虑其他集成选项（例如，混搭）。</li>
<li>如果数据存储在 Salesforce 中，是否应刷新数据以响应远程系统中的事件？</li>
<li>数据是否应定期刷新？</li>
<li>数据是否支持主要业务流程？</li>
<li>Salesforce 中是否有受此数据可用性影响的分析（报告）要求？</li>
</ul>

**解决方案**

下表包含此集成问题的各种解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>适合</th>
    <th>数据母版</th>
    <th>评论</th>
  </tr>
  <tr>
    <td>通过第三方 ETL 工具复制</td>
    <td>最佳</td>
    <td>远程系统</td>
    <td>当外部系统需要向 Salesforce 发送大量数据时，利用第三方 ETL 工具，允许您对源数据运行变更数据捕获。<br/> <br/> 
    该工具对源数据集的变化做出反应，转换数据，然后调用 Salesforce 批量 API 发出 DML 语句。如果记录数量较少，也可以使用 Salesforce REST API 实施。</td>
  </tr>
  <tr>
    <td>通过第三方 ETL 工具复制</td>
    <td>好</td>
    <td>Salesforce</td>
    <td>利用第三方 ETL 工具，允许您根据 ERP 和 Salesforce 数据集运行变更数据捕获。<br/> <br/> 
    在此解决方案中，Salesforce 是数据源，您可以使用单个行上的时间/状态信息来查询数据并筛选目标结果集。这可以通过使用批量 API 2.0 或标准 REST API 来实现（如果记录数量较少）。</td>
  </tr>
  <tr>
    <td>数据导入向导和数据加载器</td>
    <td>适合</td>
    <td>Salesforce/外部系统</td>
    <td>数据导入向导和数据加载器可用于导入、导出和迁移数据。虽然 Data Loader 命令也可以通过脚本来自动导入和导出数据，但命令行界面仅适用于 Windows。这两个工具都不是数据集成策略的推荐基础。相反，它们应该补充您的数据管理和维护策略。<br/> <br/> 
    有关 Data Loader 的更多信息，请查看<a href="https://developer.salesforce.com/tools/data-loader">这里。</a></td>
  </tr>
  <tr>
    <td>远程呼叫</td>
    <td>次优</td>
    <td>远程系统</td>
    <td>远程系统可以使用其中一个 API 调用 Salesforce，并在发生时执行数据更新。但是，这会导致两个系统之间出现大量的持续流量。<br/> <br/> 
    应更加重视错误处理和锁定。这种模式有可能导致持续更新，从而可能影响最终用户的性能。</td>
  </tr>
    <tr>
    <td>远程进程调用</td>
    <td>次优</td>
    <td>Salesforce</td>
    <td>Salesforce 可以调用远程系统并在发生时执行数据更新。但是，这会导致两个系统之间出现大量的持续流量。<br/> <br/> 
    应更加重视错误处理和锁定。这种模式有可能导致持续更新，从而可能影响最终用户的性能。</td>
  </tr>
</table>

**草图**

下图说明了此模式中的事件顺序，其中 Salesforce 是数据主数据。

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Integration Patterns - Batch.png"/>

<a href="https://a.sfdcstatic.com/developer-website/prod/assets/architect/pdf/integration-patterns/Integration Patterns - Batch.pdf">下载图表</a><br />

下图说明了随后近乎实时的事件同步，其中 Salesforce 是数据主数据。

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/CDC Salesforce Master.png" />

**结果**

在以下情况下，您可以将外部来源的数据与 Salesforce 集成：

<ul>
  <li>外部系统是数据主系统 — Salesforce 是单个源系统或多个系统提供的数据的使用者。在这种情况下，在数据导入 Salesforce 之前，通常会有一个数据仓库或数据集市来聚合数据。</li>
  <li>Salesforce 是数据主 — Salesforce 是特定实体的记录系统，Salesforce 变更数据捕获客户端应用程序可以获悉 Salesforce 数据的变更。</li>
</ul>

在典型的 Salesforce 集成场景中，实施团队会执行以下操作之一：

<ul>
  <li>在源数据集上实施变更数据捕获。</li>
  <li>在中间本地数据库中实施一组支持的数据库结构，称为控制表。</li>
</ul>

然后，ETL 工具用于创建将：

<ol>
  <li>读取控制表以确定作业的上次运行时间，并提取所需的任何其他控制值。</li>
  <li>将以上控制值用作筛选器，并查询源数据集。</li>
  <li>应用预定义的处理规则，包括验证、丰富等。</li>
  <li>使用 ETL 工具的可用连接器/转换功能创建目标数据集。</li>
  <li>将数据集写入 Salesforce 对象。</li>
  <li>如果处理成功，请更新控制表中的控制值。</li>
  <li>如果处理失败，请使用启用重新启动和退出的值更新控制表。</li>
</ol>

**备注**:我们建议您在 ETL 工具有权访问的环境中创建控制表和相关数据结构，即使无法访问 Salesforce。这提供了足够的弹性。在此过程中，Salesforce 应被视为轮辐，ETL 基础设施是中心。

要使 ETL 工具从数据同步功能中获得最大好处，请考虑以下事项：

<ul>
  <li>对 ETL 作业进行链和排序，以提供一致的流程。</li>
  <li>使用两个系统中的主键匹配传入数据。</li>
  <li>使用特定 API 方法仅提取更新的数据。</li>
  <li>如果在主-详细信息或查找关系中导入子记录，请在源位置使用父密钥对导入的数据分组，以避免锁定。例如，如果您正在导入联系人数据，请确保按父客户密钥分组联系人数据，以便在一次 API 调用中加载单个客户的最大联系人数量。无法对导入的数据分组通常会导致加载第一个联系人记录，以及该客户的后续联系人记录在 API 调用上下文中失败。</li>
  <li>任何导入后处理，例如触发器，应仅有选择地处理数据。</li>
  <li>如果场景涉及大量数据，请遵循 Trailhead 模块中的最佳实践 大数据量部署的<a href="https://developer.salesforce.com/page/Best_Practices_for_Deployments_with_Large_Data_Volumes">最佳实践</a></li>.
  
</ul>

**错误处理和恢复**

必须将错误处理和恢复策略视为整体解决方案的一部分。最佳方法取决于您选择的解决方案。

<table>
<tr>
<th>错误位置</th>
<th>错误处理和恢复策略</th>
</tr>
<tr>
<td>使用变更数据捕获 Salesforce 读取</td>
<td>
<ul>
  <li>错误处理 - 必须在远程服务中执行错误处理，因为事件有效地移交给远程系统进行进一步处理。由于此模式异步，远程系统会处理消息队列、处理和错误处理。此外，变更数据捕获事件不会在数据库事务中处理。因此，已发布的事件无法在事务中回滚。</li>
  <li>恢复 — 由于此模式异步，远程系统必须根据服务质量要求启动重试。与每个变更数据捕获事件关联的重放 ID 是原子性的，并随着每个事件的发布而增加。此 ID 可用于从特定事件重放流（例如，基于上次成功捕获的事件）。高用量平台事件消息存储 72 小时（3 天）。在使用 CometD 客户端订阅渠道时，您可以检索过去的事件消息。</li>
</ul>
</td>
</tr>
<tr>
<td>使用第三方 ETL 系统从 Salesforce 读取</td>
<td>
<ul>
  <li>错误处理 — 如果在读取操作期间出现错误，请对与基础设施无关的错误实施重试。如果重复失败，应在 ETL 操作的上下文中实施使用控制表/错误表的标准处理，以便：
  <ul>
    <li>记录错误</li>
    <li>重试读取操作</li>
    <li>不成功时终止</li>
    <li>发送通知</li>
  </ul>
  </li>
  <li>恢复 — 重新启动 ETL 进程，从失败的读取操作中恢复。</li>
</ul>
如果操作成功但有失败的记录，立即重新启动或随后执行作业应可解决问题。在这种情况下，延迟重新启动可能是一个更好的解决方案，因为它留出了时间来分类和纠正可能导致错误的数据。
</td>
</tr>
<tr>
<td>写入 Salesforce</td>
<td>
<ul>
  <li>错误处理 - 写入操作期间发生的错误可能由应用程序中的因素组合引起。API 调用返回的结果集包含以下列出的信息。此信息应用于重试写入操作（如有必要）。
  <ul>
    <li>记录识别信息</li>
    <li>成功/失败通知</li>
    <li>每个记录的错误集合</li>
  </ul>
  </li>
  <li>恢复 — 重新启动 ETL 进程，从失败的读取操作中恢复。</li>
</ul>
如果操作成功但有失败的记录，立即重新启动或随后执行作业应可解决问题。在这种情况下，延迟重新启动可能是一个更好的解决方案，因为它留出了时间来分类和纠正可能导致错误的数据。
</td>
</tr>
<tr>
<td>外部主系统</td>
<td>应根据主系统的最佳实践处理错误。</td>
</tr>
</table>

**安全注意事项**

对远程系统的任何调用必须保持请求的机密性、完整性和可用性。不同的安全注意事项适用，这取决于您选择的解决方案。

<ul>
  <li>需要至少具有“仅 API”用户权限的 Lightning 平台许可证，才可以允许经过身份验证的 API 访问 Salesforce API。</li>
  <li>我们建议使用标准加密来保护密码访问的安全。</li>
  <li>在调用 Salesforce API 时使用 HTTPS 协议。如有必要，您还可以通过内部安全解决方案将流量代理到 Salesforce API。</li>
</ul>

请参阅<a href="#附录-b安全注意事项">安全注意事项</a>。

**侧栏**

无。

**及时性**

在这种模式中，及时性并不重要。但必须注意设计界面，以便所有批处理流程在指定的批处理窗口中完成。

与所有面向批处理的操作一样，我们强烈建议您在批处理窗口期间注意隔离源和目标系统。在工作时间加载批次可能会导致一些争用，导致用户更新失败，或者更重要的是，批次加载（或部分批次加载）失败。

对于拥有全局操作的组织，同时运行所有批处理流程可能不可行，因为系统可能会继续使用。在这些情况下，可以使用使用记录类型和其他筛选条件的数据细分技术来避免数据竞争。

**状态管理**

您可以通过在两个系统之间使用代理密钥来实施状态管理。如果您需要跨 Salesforce 实体的任何类型的事务管理，我们建议您使用 Apex 使用<a href="#远程呼叫">远程呼叫</a>模式。

标准乐观记录锁定发生在平台上，使用 API 进行的任何更新都需要正在编辑记录的用户刷新记录并启动他们的事务。在 Salesforce API 的上下文中，乐观锁定是指以下过程：

<ul>
  <li>Salesforce 不会维护特定用户正在编辑的记录的状态。</li>
  <li>读取时，它会记录提取数据的时间。</li>
  <li>如果用户更新并保存记录，Salesforce 会检查其他用户是否在此期间更新了记录。</li>
  <li>如果记录已更新，系统会通知用户已更新，用户应在继续更新前检索记录的最新版本。</li>
</ul>

**中间件功能**

用于实施这种模式的最有效的外部技术是传统的 ETL 工具。重要的是，选择的中间件工具支持 Salesforce 批量 API。

中间件工具支持 getUpdated() 函数很有帮助，但不是关键。此功能提供了与 Salesforce 平台上的标准变更数据捕获功能最接近的实施。

下表强调了参与此模式的中间件系统的理想属性。

<table>
    <tr>
      <th>房地产</th>
      <th>强制</th>
      <th>理想</th>
      <th>不需要</th>
    </tr>
    <tr>
      <td>事件处理</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>协议转换</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>翻译和转换</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>排队和缓冲</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>同步传输协议</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>异步传输协议</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>中介路由</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>流程编排和服务编排</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>事务性（加密、签名、可靠交付、事务管理）</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>路由</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>提取、转换和加载</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>长时间投票</td>
      <td align="center">X（Salesforce 变更数据捕获所需）</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    
  </table>

**示例**

公用事业公司使用基于大型机的批处理流程，将潜在客户分配给个人销售代表和团队。此信息需要每晚导入 Salesforce。

客户决定使用商业可用的 ETL 工具在源表上实施变更数据捕获。解决方案的工作原理如下：

<ul>
<li>类似 Cron 的计划程序执行将潜在客户分配给用户和团队的批处理作业。</li>
<li>在批处理作业运行并更新数据后，ETL 工具会使用变更数据捕获识别这些变更。ETL 工具会整理数据存储中的更改。</li>
<li>ETL 连接器使用 Salesforce REST API 将更改加载到 Salesforce。</li>
</ul>

## 远程呼叫

**上下文**

您可以使用 Salesforce 跟踪潜在客户、管理漏斗、创建业务机会并捕获将潜在客户转换为客户的订单详细信息。Salesforce 系统会在内部创建订单，然后将该数据推送到外部计费系统进行配置和激活。开单订单由外部（远程）系统管理。当计费系统状态上的订单或计费实体发生变化时，该远程系统需要更新 Salesforce 中的订单状态。

**问题**

远程系统如何连接 Salesforce 并进行身份验证，以通知 Salesforce 外部事件、创建记录和更新现有记录？

**武力**

在应用基于此模式的解决方案时，需要考虑各种因素：

<ul>
  <li>远程调用 Salesforce 的目的是通知 Salesforce 使用事件驱动的架构在外部发生的事件？还是对特定记录执行 CRUD 操作？如果您使用事件驱动的架构，事件生产者（远程进程）将从 Salesforce 事件使用者中分离出来。</li>
  <li>对 Salesforce 的调用是否需要远程进程在继续处理之前等待响应？对 Salesforce 的远程调用始终是同步请求-回复，但如果不需要模拟异步调用，远程进程可以丢弃该响应。</li>
  <li>每个事务是针对单个 Salesforce 对象还是多个相关对象操作的？</li>
  <li>消息的格式是什么（例如，SOAP 或 REST，或者两者都通过 HTTP）？</li>
  <li>消息大小是相对较小还是较大？</li>
  <li>如果远程系统支持 SOAP，远程系统是否能够参与 Salesforce 指定合同的“合同优先”方法？在使用 SOAP API 时，这是必需的，为此提供了预定义的 WSDL。</li>
  <li>是否需要事务处理？</li>
  <li>您对 Salesforce 中自定义的容忍程度如何？</li>
</ul>

**解决方案**

此表包含此集成问题的各种解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>适合</th>
    <th>评论</th>
  </tr>
  <tr>
    <td>复合 API</td>
    <td>最佳</td>
    <td>Salesforce 提供复合 API，它基本上是一个 REST API，并支持复合请求。远程系统可以使用它：
    <ul>
      <li>一次呼叫最多发送 25 个请求。</li>
      <li>用于使用 JSON 请求在 Salesforce 组织中查询、创建和修改数据。</li>
    </ul>
    <br/> 
    同步 API — 进行 API 调用后，远程客户端应用程序会等待，直到收到服务的响应。<br/> <br/> 
    事务/提交行为 — 默认情况下，如果一些记录被标记为错误，复合 API 不允许部分成功。可以通过将“全部或全部”标记为假来更改，这将允许部分成功。<br/> <br/> 
    错误处理：正确的错误处理应检查响应正文，而不仅仅是 HTTP 状态代码。复合端点使用 200 HTTP 状态代码进行响应，即使在响应正文中，也会显示其中一个子请求失败，事务必须回滚。
    </td>
  </tr>
  <tr>
    <td>REST API</td>
    <td>最佳</td>
    <td>可访问性 — Salesforce 提供 REST API，远程系统可以使用它：
    <ul>
      <li>发布事件以通知您的 Salesforce 组织</li>
      <li>查询贵组织中的数据</li>
      <li>创建、更新和删除数据</li>
      <li>获取有关贵组织的元数据</li>
    </ul>
    <br/> 
    同步 API — 进行 API 调用后，远程客户端应用程序会等待，直到收到服务的响应。<br/> <br/> 
    REST API 遵循基于登录用户简档在 Salesforce 中配置的对象级和字段级安全性。<br/> <br/> 
    REST 将资源（实体/对象）公开为 URI，并使用 HTTP 动词定义这些资源上的 CRUD 操作。与 SOAP 不同，REST API 不需要预定义的合同，使用 XML 和 JSON 进行响应，并且具有松散的类型。REST API 是轻量级的，并提供与 Salesforce 交互的简单方法。它的优势包括易于集成和开发，是与移动应用程序和网络应用程序一起使用的绝佳选择。<br/> <br/> 
    事务/提交行为 - 默认情况下，每个记录被视为单独的事务并单独提交。一个记录更改失败不会导致其他记录更改的回滚。此行为可以更改为“全部或全部”行为。使用 REST API 复合资源，在一次 API 调用中进行一系列更新。<br/> <br/> 
    批量数据 - 任何包含超过 2000 条记录的数据操作都是批量 API 2.0 的理想选择，可用于成功准备、执行和管理使用批量框架的异步工作流。
    </td>
  </tr>
  <tr>
  <td>Bulk API 2.0</td>
  <td>最适合批量操作</td>
  <td>批量 API 2.0 是 Salesforce 用于处理大规模数据操作的现代化简化 API。基于 REST 的批量 API 2.0 提供了一个编程选项，以在您的 Salesforce 组织中异步插入、更新插入、查询或删除大型数据集。当您需要将大量数据加载到 Salesforce 中或对贵组织的数据执行批量查询时，它旨在提高效率。<br/> <br/> 
  与批量 API 1.0 不同，批量 API 2.0 总是并行处理批次，并且不支持串行模式。这意味着：
  <ul>
    <li>记录在多个线程中同时处理</li>
    <li>不保证批次之间的处理顺序</li>
    <li>性能更高，但也可能存在锁定冲突</li>
  </ul>
    <br/>
  批量 API 2.0 中的每个批次都作为自己的事务处理。这意味着：
  <ul>
    <li>成功批次独立提交</li>
    <li>失败的批次不会影响成功的批次</li>
    <li>默认情况下，所有作业之间没有“全有或全无”行为</li>
  </ul>
    <br/>
  虽然 SOAP API 也可用于处理大量记录，但当数据集包含数十万到数百万条记录时，它会变得不太理想。这是因为其相对较高的开销和较低的性能特征。
    <ul>
      <li>事件驱动的架构 - 平台事件的定义与您定义 Salesforce 对象的方式相同。通过批量 API 2.0 发布事件与创建 Salesforce 记录相同。仅支持创建和插入操作。批处理作业处理时，批次中的事件会异步发布到 Salesforce 事件总线。</li>
    </ul>
  </td>
  </tr>
  <tr>
    <td>发布/订阅 API</td>
    <td>最佳</td>
    <td>
    发布/订阅 API 是外部发布者在事件总线上发布事件的推荐方式。<br/> <br/> 
    发布/订阅 API 是一个基于 gRPC 的 API，允许外部系统发布平台事件。发布/订阅 API：
    <ul>
      <li>支持从外部应用程序发布和订阅平台事件</li>
      <li>通过正确身份验证可用（OAuth、JWT 或会话令牌）</li>
    </ul>
    <br/> 
    在 Salesforce 中定义平台事件后，内部和外部消费者都可以使用它。
    </td>
  </tr>
  <tr>
    <td>平台事件</td>
    <td>最佳</td>
    <td>
    平台事件的定义与您定义 Salesforce 对象的方式相同。平台事件可以使用不同的机制发布，例如 REST API、批量 API 和 SOAP API。
    <br/> <br/> 
    通过 REST API 发布事件与创建 Salesforce 记录相同。
    <br/> <br/> 
    端点格式：POST /services/data/vXX.X/sobjects/EventName__e/
    <ul>
      <li>Content-Type：application/json</li>
      <li>身份验证：不记名标记 (OAuth)</li>
    </ul>
    <br/> 
    使用批量 API，仅支持创建和插入操作。批处理作业处理时，批次中的事件会异步发布到 Salesforce 事件总线。
    <br/> <br/> 
    由于平台事件是 SObject，因此支持标准 SOAP API 操作。
    </td>
  </tr>
  <tr>
    <td>SOAP API</td>
    <td>适合</td>
    <td>
    可访问性 — Salesforce 提供远程系统可用于以下操作的 SOAP API：
    <ul>
      <li>发布事件以通知您的 Salesforce 组织</li>
      <li>查询贵组织中的数据</li>
      <li>创建、更新和删除数据</li>
      <li>获取有关贵组织的元数据</li>
      <li>运行实用程序以执行管理任务</li>
    </ul>
    <br/> 
    同步 API — 进行 API 调用后，远程客户端应用程序会等待，直到收到服务的响应。不支持对 Salesforce 的异步调用。
    <br/> <br/> 
    生成的 WSDL — Salesforce 为远程系统提供两个 WSDL：
    <ul>
      <li>Enterprise WSDL - 提供特定于 Salesforce 组织的强类型 WSDL。</li>
      <li>Partner WSDL - 包含非特定于 Salesforce 组织的松散类型 WSDL。</li>
    </ul>
    <br/> 
    安全性 — 执行 SOAP API 的客户端必须拥有有效的登录并获得会话，以执行任何 API 调用。API 遵循基于登录用户简档在 Salesforce 中配置的对象级和字段级安全性。
    <br/> <br/> 
    事务/提交行为 — 默认情况下，如果一些记录被标记为错误，每个 API 调用允许部分成功。这可以更改为“全有或全无”行为，如果出现任何错误，将回滚所有结果。事务无法跨越多个 API 调用。为了克服这一限制，单个 API 调用可能会影响多个对象。
    </td>
  </tr>
  <tr>
    <td>Apex Web 服务</td>
    <td>次优</td>
    <td>
    Apex 类方法可以作为 Web 服务方法向外部应用程序公开。此方法是 SOAP API 的替代方法，通常仅在必须满足以下附加要求时使用。
    <ul>
      <li>需要完整的事务支持（例如，在一个事务中创建客户、联系人和业务机会）。</li>
      <li>提交前，自定义逻辑必须在 Salesforce 侧应用。</li>
    </ul>
    <br/> 
    使用 Apex Web 服务的好处必须与需要在 Salesforce 中维护的其他代码进行权衡。
    <br/> <br/> 
    不适用于平台事件，因为使用者处的事务预插入逻辑不适用于
    事件驱动的架构。要通知 Salesforce 组织某个事件已经发生，请使用 SOAP API、REST API 或批量 API 2.0。
    </td>
  </tr>
  <tr>
    <td>Apex REST 服务</td>
    <td>次优</td>
    <td>
    Apex 类可以公开为映射到特定 URI 的 REST 资源，带有定义的 HTTP 动词（例如 POST 或 GET）。
    <br/> <br/> 
    您可以使用 REST API 复合资源在单个事务中执行多个更新。
    <br/> <br/> 
    与 SOAP 不同，客户端无需使用服务定义/合同 (WSDL) 并生成客户端存根。远程系统只需要能够形成 HTTP 请求并处理返回的结果（XML 或 JSON）。
    <br/> <br/> 
    不适用于平台事件，因为使用者处的事务预插入逻辑不适用于
    事件驱动的架构。要通知 Salesforce 组织某个事件已经发生，请使用 SOAP API、REST API 或批量 API 2.0。
    </td>
  </tr>
</table>

**草图**

以下图表说明了当您使用 REST API 从外部事件通知或 SOAP API 查询 Salesforce 对象来实施此模式时的事件顺序。使用 REST API 时，事件的顺序相同。

_远程系统通过 SOAP API 查询 Salesforce_

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Remote System Querying Salesforce Via SOAP API.png"/>

_通过 REST API 远程系统通知 Salesforce 事件_

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Remote System Notifying Salesforce with Events Via REST API.png"/>

**结果**

在事件驱动的架构中，远程系统使用 SOAP API、REST API 或批量 API 2.0 调用 Salesforce，以将事件发布到 Salesforce 事件总线。发布事件会通知所有订阅者。事件订阅者可以在 Salesforce 平台上使用，例如 Flows，或 Lightning 组件、Apex 触发器。事件订阅者也可以是 Salesforce 平台的外部，例如 CometD 订阅者。

当直接使用 Salesforce 对象时，与此模式相关的解决方案允许：

<ul>
  <li>远程系统调用 Salesforce API 查询数据库并执行单对象操作（创建、更新、删除等）。</li>
  <li>远程系统调用 Salesforce REST API 复合资源，以执行一系列对象操作。</li>
  <li>远程系统调用自定义构建的 Salesforce API（服务），该 API 可以支持多对象事务操作和自定义预/后处理逻辑。</li>
</ul>

**调用机制**

调用机制取决于为实施此模式选择的解决方案。

<table>
<tr>
  <th>调用机制</th>
  <th>描述</th>
</tr>
<tr>
  <td>SOAP API</td>
  <td>远程系统使用 Salesforce Enterprise 或 Partner WSDL 生成客户端存根，然后用于调用标准 SOAP API。</td>
</tr>
<tr>
  <td>REST API</td>
  <td>在访问任何 Apex REST 服务之前，远程系统必须进行身份验证。远程系统可以使用 OAuth 2.0 或用户名和密码身份验证。无论哪种情况，客户端都必须使用适当的值设置授权 HTTP 标题（可以通过对 SOAP API 的登录调用来获取 OAuth 访问令牌或会话 ID）。<br/> <br/> 
  然后，远程系统使用适当的动词生成 REST 调用（HTTP 请求），并处理返回的结果（支持 JSON 和 XML 数据格式）。</td>
</tr>
<tr>
  <td>Apex Web 服务</td>
  <td>远程系统使用自定义 Apex Web 服务 WSDL 生成客户端存根，这些存根又用于调用自定义 Apex Web 服务。</td>
</tr>
<tr>
  <td>Apex REST 服务</td>
  <td>根据 REST API，使用 @RestResource、@HttpGet 和 @HttpPost 注解定义资源 URI 和适用动词。</td>
</tr>
<tr>
  <td>Bulk API 2.0</td>
  <td>批量 API 2.0 是基于 REST 的 API，因此适用与 REST API 相同的调用机制。</td>
</tr>
<tr>
  <td>REST API 调用流</td>
  <td>使用 REST API 调用自定义可调用操作端点，以调用自动启动的流。</td>
</tr>
</table>

**错误处理和恢复**

必须将错误处理和恢复策略视为整体解决方案的一部分。

<ul>
  <li>错误处理 — 所有远程调用方法、标准或自定义 API 都需要远程系统处理任何后续错误，例如超时和重试管理。中间件可用于提供错误处理和恢复的逻辑。</li>
  <li>恢复 — 如果服务质量要求，需要创建自定义重试机制。在这种情况下，确保幂等设计特性非常重要。平台事件使订阅者能够使用重放 ID 在这些消息发布后的某个时间段内获取消息。</li>
</ul>

**幂等设计注意事项**

幂等功能保证重复调用是安全的，并且不会产生负面影响。如果未实施幂等，则重复调用同一消息会产生不同的结果，并可能导致数据完整性问题，例如，创建重复记录、重复处理事务等。

在错误或超时的情况下，远程系统必须管理多个（重复）调用，以避免重复插入和冗余更新（特别是在触发下游触发器和工作流规则时）。虽然可以在 Salesforce 中管理其中一些情况（特别是在自定义 SOAP 和 REST 服务的情况下），但我们建议远程系统（或中间件）管理错误处理和幂等设计。

**安全注意事项**

不同的安全注意事项适用，这取决于您选择的模式解决方案。在所有情况下，平台使用登录用户的访问权限（例如，简档设置、共享规则、权限集等）。此外，简档 IP 限制可用于限制对特定 IP 地址范围的 API 的访问。

<table>
<tr>
  <th>解决方案</th>
  <th>安全注意事项</th>
</tr>
<tr>
  <td>SOAP API</td>
  <td>alesforce 支持安全套接字层 v3 (SSL) 和传输层安全性 (TLS) 协议。密码的密钥长度必须至少为 128 位。<br/> <br/> 
  远程系统必须使用有效凭据登录，以获取会话 ID。如果远程系统已经拥有有效的会话 ID，那么它可以调用 API，而无需显式登录。这在本文档前面介绍的回调模式中使用，其中前面的 Salesforce 出站消息包含会话 ID 和记录 ID，供以后使用。<br/> <br/> 
  我们建议调用 SOAP API 的客户端缓存并重复使用会话 ID，以最大限度地提高性能，而不是为每个调用获取新的会话 ID。</td>
</tr>
<tr>
  <td>REST API</td>
  <td>我们建议远程系统建立 OAuth Trust 进行授权。然后，可以使用 HTTP 动词对特定资源进行 REST 调用。也可以使用可能通过其他方式获得的有效会话 ID 进行 REST 调用（例如，通过调用 SOAP API 检索或通过出站消息提供）。<br/> <br/> 
  我们建议调用 REST API 的客户端缓存并重复使用会话 ID，以最大限度地提高性能，而不是为每个调用获取新的会话 ID。</td>
</tr>
<tr>
  <td>Apex Web 服务</td>
  <td>我们建议远程系统建立 OAuth Trust 进行授权。</td>
</tr>
<tr>
  <td>Apex REST 服务</td>
  <td>我们建议远程系统建立 OAuth Trust 进行授权。</td>
</tr>
<tr>
  <td>Bulk API 2.0</td>
  <td>我们建议远程系统建立 OAuth Trust 进行授权。</td>
</tr>
</table>

请参阅<a href="#附录-b安全注意事项">安全注意事项</a>。

**侧栏**

无。

**及时性**

SOAP API 和 Apex Web 服务 API 是同步的。以下超时适用：

<ul>
  <li>会话超时 — 如果根据 Salesforce 组织的会话超时设置没有活动，会话超时。</li>
  <li>查询超时 — 每个 SOQL 查询的单个超时限制为 120 秒。</li>
</ul>

**数据量**

数据量注意事项取决于您选择的解决方案和通信类型。

<table>
  <tr>
    <th>解决方案</th>
    <th>通信类型</th>
    <th>限制</th>
  </tr>
  <tr>
    <td>SOAP API 或 REST API</td>
    <td>Synchronous</td>
    <td>
      <ul>
        <li>SOAP 登录 — SOAP 登录请求大小限制为 10 KB 或更小。每个用户每小时最多可以调用 3600 次 login() 函数。如果您超过此限制，API 会返回错误。</li>
        <li>创建、更新、删除 — 远程系统一次最多可以创建、更新或删除 200 条记录。可以多次调用来处理总共 200 多条记录，但每个请求的大小限制为 200 条记录</li>
        <li>BLOB 数据 — 您可以使用 SObject 基本信息、SObject 行或 SObject 集合 REST 资源，以在 Salesforce 标准对象中插入或更新 BLOB 数据。对于 SObject 基本信息或 SObject 行资源，上传的最大文件大小对于 ContentVersion 对象为 2 GB，对于所有其他合格的标准对象为 500 MB。使用 SObject Collections 资源，单个请求中所有文件的最大总大小为 500 MB。</li>
        <li>查询结果大小 — 默认情况下，在查询结果对象中返回的行数（批次大小）、在 query() 或 queryMore() 调用中返回的行数设置为 500。返回的最大行数是 2,000。您可以明确设置批次大小，但不能保证请求的批次大小就是实际批次大小。这样做是为了最大限度地提高性能。当要返回的行数超过批次大小时，使用 queryMore() API 调用来迭代多个批次。其他规则可能适用，因此，有关更多信息。</li>
      <li>事件消息 — 最大事件消息大小为 1 MB。使用 Salesforce API 发布事件将计入标准 API 限制。</li>
      </ul>
    </td>
  </tr>
  <tr>
    <td>Bulk API 2.0</td>
    <td>Asynchronous</td>
    <td>批量 API 2.0 针对异步导入和导出大型数据集进行了优化。<br/> <br/> 
    任何包含超过 2000 条记录的数据操作都是批量 API 2.0 的理想选择，有助于成功准备、执行和管理使用批量框架的异步工作流。少于 2000 条记录的作业应涉及 REST（例如，复合）或 SOAP 中的“批量化”同步调用。<br/> <br/> 
    批量 API 2.0 在提交批量请求和相关数据时是同步的。数据的实际处理异步发生。有关 API 和批处理限制的更多信息，请参阅<a href="https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/bulk_common_limits.htm">限制</a>。</td>
  </tr>
</table>

**端点功能和标准支持**

端点的功能和标准支持取决于您选择的解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>端点注意事项</th>
  </tr>
  <tr>
    <td>SOAP API</td>
    <td>远程系统必须能够基于 Salesforce 预定义的消息格式实施可以调用 Salesforce SOAP API 的客户端。<br/> <br/> 
    远程系统（客户端）必须参与合同优先的实施，其中合同由 Salesforce 提供（例如，Enterprise 或 Partner WSDL）。</td>
  </tr>
  <tr>
    <td>REST API</td>
    <td>远程系统必须能够实施调用 Salesforce 定义的 REST 服务并处理 XML 或 JSON 结果的 REST 客户端。</td>
  </tr>
  <tr>
    <td>Apex Web 服务</td>
    <td>远程系统必须能够实施可以调用 Salesforce 定义的预定义格式的 SOAP 消息的客户端。<br/> <br/> 
    远程系统必须参与代码优先实施，其中合同在实施 Apex Web 服务后由 Salesforce 提供。每个 Apex Web 服务都有自己的 WSDL。
    </td>
  </tr>
  <tr>
    <td>Apex REST 服务</td>
    <td>与 REST API 相同的端点注意事项适用。</td>
  </tr>
</table>

**状态管理**

在集成系统时，密钥对于持续的状态跟踪非常重要，例如，如果记录在远程系统中创建，以支持对该记录的持续更新。有两个选项：

<ul>
  <li>Salesforce 存储远程记录的主或唯一代理密钥。</li>
  <li>远程系统存储 Salesforce 唯一记录 ID 或其他一些唯一代理密钥。在此同步模式中，处理集成密钥有一些特定的注意事项。</li>
</ul>

<table>
<tr>
  <th>师父</th>
  <th>系统	描述</th>
</tr>
<tr>
  <td>Salesforce</td>
  <td>在这种情况下，远程系统会存储 Salesforce RecordId 或记录中的一些其他唯一替代密钥。</td>
</tr>
<tr>
  <td>远程系统</td>
  <td>在这种情况下，Salesforce 会在远程系统中存储对唯一标识符的引用。因为进程是同步的，所以密钥可以作为同一事务的一部分使用外部 ID 字段提供。</td>
</tr>
</table>

**复杂集成场景**

在处理复杂的集成场景（例如转换和流程编排）时，此模式中的每个解决方案都有不同的注意事项。

<table>
  <tr>
    <th>解决方案</th>
    <th>注意事项</th>
  </tr>
  <tr>
    <td>SOAP API 或 REST API</td>
    <td>SOAP API 和 REST API 提供对象上的简单事务。无法在 Salesforce 中执行复杂的集成场景，例如聚合、编排和转换。这些场景必须由远程系统或中间件处理，而中间件是首选方法。</td>
  </tr>
  <tr>
    <td>Apex Web 服务或 Apex REST 服务</td>
    <td>自定义 Web 服务可以提供跨对象功能、自定义逻辑和更复杂的事务支持。此解决方案应谨慎使用，并且您应始终考虑中间件是否适合任何转换、编排和错误处理逻辑。</td>
  </tr>
</table>

**州长限制**

由于 Salesforce 平台的多租户性质，在使用 API 时存在限制。

<table>
  <tr>
    <th>解决方案</th>
    <th>限制</th>
  </tr>
  <tr>
    <td>SOAP API、REST API 和自定义 Apex API</td>
    <td>
      <ul>
        <li>API 请求限制 - Salesforce 对每 24 小时周期的 API 调用次数应用限制。限制取决于 Salesforce 版本类型和许可证数量。例如，Unlimited Edition 每 24 小时为每个 Salesforce Platform 许可证提供 5,000 个 API 请求。有关更多信息，请查看 <a href="https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm">Salesforce 开发人员限制和分配快速参考</a>。</li>
        <li>API 查询光标限制 — 用户一次最多可以打开 10 个查询光标。否则，将释放 10 个光标中最早的一个。如果远程应用程序尝试打开释放的查询光标，将导致错误。例如，如果共享集成用户凭据，需要考虑最大查询光标数量。只要有可能，中间件应该在执行另一个查询（以串行方式）之前完成完整的查询，或者每个应用程序应该使用指定的集成用户。或者，中间件可能需要以“循环”方式跨多个用户执行请求。</li>
        <li>调用限制 — 有关创建、更新和查询限制，请查看数据量侧栏。</li>
      </ul>
    </td>
  </tr>
  <tr>
    <td>Bulk API 2.0</td>
    <td>有关更多信息，请查看<a href="#远程进程调用--请求和回复">数据量</a>侧栏。</td>
  </tr>
  <tr>
    <td>平台事件</td>
    <td>
      <ul>
        <li>事件通知限制 — 对于标准数量平台事件，每小时最多可以发布 100,000 个事件。对于基于高用量的平台事件，每小时最多可以发布 250,000 个事件。要监控高用量事件使用情况，请使用 REST API 限制资源。
        </li>
        <li>事件消息大小限制 - 事件消息的最大大小为 1 MB。使用 Salesforce API 发布事件将计入标准 API 限制。</li>
      </ul>
    </td>
  </tr>
</table>

**可靠消息传递**

可靠的消息传递尝试解决保证将消息传递到单个组件本身可能不可靠的远程系统的问题。Salesforce SOAP API 和 REST API 是同步的，本身不提供任何可靠的消息传递协议的明确支持（例如，WS-ReliableMessaging）。

我们建议远程系统实施可靠的消息传递系统，以确保成功管理错误和超时情况。从外部系统发布平台事件依赖于 Salesforce API，因此 SOAP API 和 REST API 的注意事项相同。

**中间件功能**

此表强调了参与此模式的中间件系统的理想属性：

<table>
    <tr>
      <th>房地产</th>
      <th>强制</th>
      <th>理想</th>
      <th>不需要</th>
    </tr>
    <tr>
      <td>事件处理</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>协议转换</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
     <tr>
      <td>翻译和转换</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>排队和缓冲</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>同步传输协议</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>异步传输协议</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>中介路由</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>流程编排和服务编排</td>
      <td align="center"></td>
      <td align="center">X</td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>事务性（加密、签名、可靠交付、事务管理）</td>
      <td align="center">X</td>
      <td align="center"></td>
      <td align="center"></td>
    </tr>
    <tr>
      <td>路由</td>
      <td align="center"></td>
      <td align="center"></td>
      <td align="center">X</td>
    </tr>
    <tr>
      <td>提取、转换和加载</td>
      <td align="center"></td>
      <td align="center">X（用于批量/批次）</td>
      <td align="center"></td>
    </tr>
  </table>

**示例**

一家打印用品和服务公司使用 Salesforce 作为前端来创建和管理打印机用品和订单。代表打印机的 Salesforce 资产记录会定期更新，其中包含本地打印机管理系统 (PMS) 的打印使用情况统计数据（墨盒状态、纸张级别），该系统定期监控客户站点上的打印机。在达到设定的阈值时（例如，墨盒状态不佳或纸张不足 30%），系统会通知对事件感兴趣的多个应用程序/进程（变量），发送电子邮件或 Chatter 提醒，并创建订单记录。PMS 存储 Salesforce ID（Salesforce 是资产记录主记录）。

以下约束适用：

<ul>
  <li>PMS 可以参与合同优先的集成，其中 Salesforce 提供合同，PMS 充当 Salesforce 服务的客户端（消费者）（通过 Enterprise 或 Partner WSDL 定义）。</li>
  <li>Salesforce 中不应有自定义开发。</li>
</ul>

此示例最好使用 Salesforce SOAP API 或 REST API 发布事件，并在 Salesforce 中使用声明自动化 (流) 来实现。使用平台事件的主要原因是订阅者数量可变且非有限；但是，对于订单等有限记录列表的简单更新，请使用 SOAP 或 REST API 更新记录。

在 Salesforce 中：

<ul>
  <li>在 Salesforce 中定义平台事件，以包含来自 PMS 的通知数据。</li>
  <li>创建由打印机事件通知触发的流。该流程会更新打印机资产并创建订单（使用自动启动的流）。</li>
  <li>下载 Enterprise 或 Partner WSDL，并将其提供给远程系统。</li>
</ul>

在远程系统中：

<ul>
<li>从 Enterprise 或 Partner WSDL 创建客户端存根。</li>
<li>使用集成用户的凭据向 Salesforce（通过 OAuth Web 服务器或不记名令牌流）进行身份验证。</li>
<li>在打印机状态事件时，PMS 会调用 API 来创建打印机状态平台事件（包含打印机使用情况统计数据）。Salesforce 事件总线通知流订阅者和所有其他订阅者。</li>
</ul>

当您使用平台事件时，事件总线允许您为高用量平台事件重放事件 72 小时。使用中间件解决方案发布这些事件有助于在发布侧包含错误处理。但是，如果您需要更高的可靠性，您可以在订阅侧实施错误处理。

此示例演示以下内容：

<ul>
<li>Salesforce 同步 API 客户端（使用者）的实施。</li>
<li>对 Salesforce 的回调，以发布平台事件（与之前涵盖的请求/回复平台事件模式保持一致）。</li>
</ul>

## 基于数据更改的 UI 更新

**上下文**

您可以使用 Salesforce 管理客户个案。客户服务代表正在与处理个案的客户通话。客户进行付款，客户服务代表需要从付款处理应用程序中查看 Salesforce 应用程序中的实时更新，这表示客户已成功支付订单的未偿金额。

**问题**

当 Salesforce 中发生事件时，如何在 Salesforce 用户界面中通知用户，而无需刷新屏幕并可能丢失工作？

**武力**

在应用基于此模式的解决方案时，需要考虑各种因素：

- 正在处理的数据是否需要存储在 Salesforce 中？
- 是否可以构建自定义用户界面层来查看这些数据？
- 用户是否有权调用自定义用户界面？

**解决方案**

解决此集成问题的推荐解决方案是使用平台事件，这将确保 Salesforce 中近乎实时的事件。平台事件提供了独立于任何 Salesforce 对象的结构化灵活负载。它还确保持久的主题，重放窗口为 72 小时。这确保了事件可用，即使离线消费者稍后可用。此解决方案由以下组件组成：

- Apex 触发器或流，带有在主题上发布平台事件的逻辑
- 允许您从 Apex 触发器或流发布事件的主题
- 基于 JavaScript 的 <a href="https://docs.cometd.org/current4/reference/#_bayeux">Bayeux</a> 协议实现 (现为 <a href="https://docs.cometd.org/">CometD</a> ) , 可由用户界面使用
- Lightning 组件
- 作为静态资源包含的 JavaScript 库

**草图**

下图说明了如何实施串流 API，将通知串流到 Salesforce 用户界面。这些通知由 Salesforce 中的记录更改触发。

_数据更改触发的 Salesforce 中的 UI 更新_

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Integration Patterns - UI Update.png"/>

**结果**

**优点**

应用与此模式相关的解决方案具有以下好处：

<ul>
  <li>无需编写自定义轮询机制</li>
  <li>无需用户发起的反馈循环</li>
</ul>

**不支持的要求**

该解决方案具有以下局限性：

<ul>
  <li>不保证通知的送达。</li>
  <li>不保证通知的顺序。</li>
  <li>通知不会从批量 API 所做的记录更改中生成。</li>
</ul>

**安全注意事项**

遵守标准 Salesforce 组织级安全性。建议您使用 HTTPS 协议连接到串流 API。请参阅<a href="#附录-b安全注意事项">安全注意事项</a>

**侧栏**

最佳解决方案包括在 Salesforce 中创建自定义用户界面。您必须考虑可用于呈现自定义用户界面的适当用户界面容器。支持的浏览器列在<a href="https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/intro_stream.htm">串流 API 开发人员指南</a>中

**示例**

一家电信公司使用 Salesforce 管理客户个案。客户服务经理希望在其中一个客户服务代表成功完成个案时收到通知。

实施此模式规定的解决方案，客户应：

<ul>
  <li>创建 Apex 触发器 PushTopic，在保存状态为“已结束”且解决方法为“成功”的个案时发送平台事件。</li>
  <li>创建客户服务经理可用的自定义用户界面。此用户界面订阅事件总线，以使用平台事件。</li>
  <li>在自定义用户界面中实施逻辑，显示该经理的客户服务代表生成的提醒。</li>
</ul>

## 数据虚拟化

**上下文**

您可以使用 Salesforce 跟踪潜在客户、管理漏斗、创建业务机会并捕获将潜在客户转换为客户的订单详细信息。但是，Salesforce 不是包含或处理订单的系统。订单由外部（远程）系统管理。但销售代表希望在 Salesforce 中查看和更新实时订单信息，而无需了解或使用外部系统。

**问题**

在 Salesforce 中，您如何查看、搜索和修改存储在 Salesforce 外部的数据，而不将数据从外部系统移到 Salesforce？

**武力**

在应用基于此模式的解决方案时，需要考虑各种因素：

<ul>
  <li>是否要在 Salesforce 中构建声明性/指点单击式出站集成或 UI 混搭？</li>
  <li>您是否有大量数据不想复制到您的 Salesforce 组织中？</li>
  <li>您是否需要随时访问少量远程系统数据？</li>
  <li>您是否需要实时访问最新数据？</li>
  <li>您是否将数据存储在云或后台系统中，但希望在 Salesforce 组织中显示或处理该数据？</li>
  <li>对于在 Salesforce 中存储特定类型的数据，您是否担心数据驻留问题？</li>
</ul>

**解决方案**

下表包含此集成问题的各种解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>适合</th>
    <th>评论</th>
  </tr>
  <tr>
    <td>Salesforce Connect</td>
    <td>最佳</td>
    <td>使用 Salesforce Connect 从外部来源访问数据，以及 Salesforce 数据。实时从 SAP、Microsoft、Oracle 等系统和其他基于云的系统（例如 Snowflake）中提取数据，而无需在 Salesforce 中复制数据。<br/> <br/> 
    Salesforce Connect 将外部系统中的数据表映射到组织中的外部对象。外部对象与自定义对象相似，只是它们映射到 Salesforce 组织外部的数据。Salesforce Connect 使用与外部数据的实时连接，以使外部对象始终处于最新状态。访问外部对象会实时从外部系统获取数据。<br/> <br/> 
    Salesforce Connect 允许您：
    <ul>
      <li>在外部系统中查询数据。</li>
      <li>在外部系统中创建、更新和删除数据。</li>
      <li>通过列表视图、详细信息页面、记录摘要、自定义选项卡和页面布局访问外部对象。</li>
      <li>定义外部对象与标准或自定义对象之间的关系，以集成来自不同来源的数据。</li>
      <li>对外部数据运行报表（有限）。</li>
      <li>查看 Salesforce 移动应用程序上的数据。</li>
    </ul>
    
要使用 Salesforce Connect 访问存储在外部系统上的数据，您可以使用以下其中一个适配器：
    
<ul>
  <li>Odata 2.0 适配器或 Odata 4.0 适配器 — 连接到任何 Odata 2.0 或 4.0 生成器公开的数据。</li>
  <li>跨组织适配器 — 连接到存储在其他 Salesforce 组织中的数据。跨组织适配器使用标准 Lightning 平台 REST API。与 Odata 不同，跨组织适配器直接连接到其他组织，而无需中间 Web 服务。</li>
  <li>通过 Apex 创建的自定义适配器 — 如果 Odata 和跨组织适配器不适合您的需求，请使用 Apex 连接器框架开发自己的适配器。</li>
</ul>
  </td>
  </tr>
  <tr>
    <td>请求和回复</td>
    <td>次优</td>
    <td>
    使用 Salesforce Web 服务 API 发出临时数据请求，以访问和更新外部系统数据。此解决方案包括以下方法： 
    <br/> <br/> 
    使用 Salesforce SOAP API。自定义页面或按钮以同步方式启动 Apex REST/SOAP 标注。在 Salesforce 中，您可以使用 WSDL 并生成生成的代理 Apex 类。该类提供了调用远程服务的必要逻辑。然后，页面上的用户发起的操作调用执行此代理 Apex 类的 Apex 控制器操作，以执行远程调用。页面需要自定义 Salesforce 应用程序。 
    <br/> <br/> 
    使用 Salesforce REST API。自定义页面或按钮以同步方式启动 Apex HTTP 标注 (REST 服务)。在 Salesforce 中，您可以使用标准 GET、POST、PUT 和 DELETE 方法调用 HTTP 服务。<br/> <br/> 
    有关此解决方案的更多信息，请查看<a href="#远程进程调用--请求和回复">远程流程调用 — 请求和回复</a>。
    </td>
  </tr>
</table>

**草图**

下图说明了如何使用 Salesforce Connect 使用 Odata 适配器从外部系统提取数据。

<img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/integration-patterns/Integration Patterns - Data Vitualization.png"/>

在这种情况下：

<ol>
  <li>浏览器执行 AJAX 调用，该调用又在相应的外部对象适配器上执行操作。</li>
  <li>适配器将操作转换为 Odata 请求，并通过集成和服务层向远程系统发出 HTTP GET 请求。</li>
  <li>远程系统通过集成和服务层向 Salesforce 返回 JSON 响应。</li>
  <li>响应从 Odata 翻译为外部对象，并显示回浏览器。</li>
</ol>

**结果**

应用与此模式相关的解决方案允许用户界面发起的调用，在这些调用中可以向最终用户显示事务的结果。

**调用机制**

调用机制取决于为实施此模式选择的解决方案。

<table>
<tr>
  <th>调用机制</th>
  <th>描述</th>
</tr>
<tr>
  <td>外部对象</td>
  <td>Salesforce Connect 将 Salesforce 外部对象映射到外部系统中的数据表。Salesforce Connect 会按需实时访问数据，而不是将数据复制到贵组织。即使数据存储在贵组织外部，Salesforce Connect 也会提供与 Lightning 平台的无缝集成。外部对象对 Salesforce 工具可用，例如全局搜索、查找关系、记录摘要和 Salesforce 移动应用程序。外部对象也适用于 Apex、SOSL、SOQL 查询、Salesforce API，并通过元数据 API、更改集和软件包进行部署。
  </td>
</tr>
<tr>
  <td>照明组件 </td>
  <td>当远程进程作为涉及用户界面的端到端进程的一部分被触发时，并且结果必须在 Salesforce 记录中显示或更新时使用。例如，向外部付款网关提交信用卡付款并立即返回向用户显示的付款结果的过程。从用户界面事件触发的集成通常需要创建自定义 Lightning 组件。</td>
</tr>
</table>

**错误处理**

将错误处理作为整体解决方案的一部分非常重要。当出现错误时（异常或错误代码返回到调用者），调用者管理错误处理。<a href="https://appexchange.salesforce.com/listingDetail?listingId=a0N3A00000EJHQ6UAP">Salesforce Connect 验证器</a>是一个免费工具，用于运行一些常见的查询和注意错误类型和失败原因。

**优点**

使用 Salesforce Connect 解决方案的一些好处是：

<ul>
  <li>此解决方案不消耗 Salesforce 中的数据存储。</li>
  <li>用户不必担心在外部系统和 Salesforce 之间定期同步数据。</li>
  <li>一种声明性设置，可通过 Odata、跨组织适配器或使用自定义 Apex 适配器的最少代码快速实现。</li>
  <li>用户可以以外部对象的形式访问外部数据，其功能与自定义对象基本相同。</li>
  <li>使用全局搜索在连接的外部系统中执行联合搜索的能力。</li>
  <li>能够运行从云和本地源访问外部数据的报表。请参阅以下报告注意事项。</li>
</ul>

**Salesforce Connect 注意事项**

Salesforce Connect 解决方案具有以下注意事项：

<ul>
<li>外部对象的行为类似于自定义对象，但一些功能对外部对象不可用。有关更多信息，请查看 <a href="https://help.salesforce.com/articleView?id=platform_connect_considerations_compatibility.htm&type=5&language=en_US">Salesforce Connect 的 Salesforce 兼容注意事项</a>。</li>
<li>外部对象会影响报表性能。有关更多信息,请参阅<a href="https://help.salesforce.com/s/articleView?id=platform.platform_connect_considerations_reports.htm&type=5">Salesforce Connect 报告注意事项</a>。</li>
<li>有关使用 Salesforce Connect 适配器的其他注意事项，请参阅 Salesforce Connect 的<a href="https://help.salesforce.com/s/articleView?id=platform.platform_connect_considerations.htm&type=5">注意事项</a> - 所有适配器。</li>
<li>如果您正在考虑使用跨组织适配器，请参阅 Salesforce Connect 的<a href="https://help.salesforce.com/s/articleView?id=platform.xorg_considerations.htm&type=5">注意事项</a> - 跨组织适配器。</li>
<li>如果您正在考虑使用 Odata 适配器，请参见 Salesforce Connect 的<a href="https://help.salesforce.com/s/articleView?id=platform.odata_considerations.htm&type=5">注意事项</a> Odata 2.0 和 4.0 适配器。</li>
<li>如果您正在考虑使用自定义 Apex 适配器，请参阅 Salesforce Connect 的<a href="https://help.salesforce.com/s/articleView?id=platform.apex_adapter_considerations.htm&type=5">注意事项</a> - 自定义适配器。</li>
</ul>

**安全注意事项**

此模式的解决方案应遵守标准的 Salesforce 组织级安全性。建议您使用 HTTPS 协议连接到任何远程系统。有关更多详细信息，请查看<a href="#附录-b安全注意事项">安全注意事项</a>

如果您正在使用 Odata 连接器，请确保您了解 Odata 外部数据源上跨站点请求伪造 (CSRF) 的特殊行为、限制和建议。有关更多信息，请查看 <a href="https://help.salesforce.com/s/articleView?id=platform.odata_considerations_csrf.htm&type=5">Salesforce Connect — OData 2.0 和 4.0 适配器的 CSRF 注意</a>事项。

**侧栏**

无。

**及时性**

及时性在这种模式中非常重要。请记住以下几点：

<ul>
  <li>通常从用户界面调用请求，因此进程不得让用户等待。</li>
  <li>根据外部系统的可用性和连接，检索外部数据可能需要很长时间。Salesforce 具有可配置的最大 120 秒超时值，以等待外部系统的响应。</li>
  <li>远程流程的完成应及时执行，并在 Salesforce 超时限制内和用户预期内完成。</li>
</ul>

**数据量**

由于 Apex 调用解决方案的请求或响应的超时值和最大大小较小，此模式主要用于小容量实时活动。请勿在消息中包含数据负载的批处理活动中使用此模式。

**端点功能和标准支持**

端点的功能和标准支持取决于您选择的解决方案。

<table>
  <tr>
    <th>解决方案</th>
    <th>端点注意事项</th>
  </tr>
  <tr>
    <td>Salesforce Connect</td>
    <td>Odata API — 使用开放数据协议访问存储在 Salesforce 外部的数据。外部数据必须通过 Odata 生成器公开。<br/> <br/> 
    其他 API — 当其他可用的适配器不适合您的需求时，使用 Apex 连接器框架开发您自己的自定义适配器。自定义适配器可以从任何来源获取数据。例如，一些数据可以通过标注从互联网检索，而其他数据可以通过编程方式操纵甚至生成。<br/> <br/> 
    连接到 Salesforce — 使用 Lightning 平台 REST API 访问存储在其他 Salesforce 组织中的数据。<br/> <br/> 
    通过中间件连接<br/> <br/> 
    通过中间件连接 — Salesforce Connect 合作伙伴生态系统与 Salesforce 密切合作，确保他们的中间件网关从他们的服务中公开 Odata 端点，以便 Salesforce 可以与他们连接，而无需编写额外的代码。
    </td>
  </tr>
  <tr>
    <td>请求和回复</td>
    <td>Apex SOAP 标注 - <br/> <br/> 
    端点必须能够通过 HTTP 接收 Web 服务调用。<br/> <br/>
    Apex HTTP Callouts - <br/> <br/> 
    端点必须能够接收 HTTP 调用。<br/> <br/> 
    您可以使用 Apex HTTP 标注，以使用标准 GET、POST、PUT 和 DELETE 方法调用 RESTful 服务
    </td>
  </tr>
</table>

**状态管理**

在集成系统时，密钥对正在进行的状态跟踪很重要。例如，如果在远程系统中创建记录，则该记录通常需要某种识别密钥来支持正在进行的更新。存储密钥有两个选项。

<ul>
  <li>Salesforce 存储远程记录的主或唯一代理密钥。</li>
  <li>远程系统存储 Salesforce 唯一记录 ID 或其他一些唯一代理密钥。在此同步模式中，处理集成密钥有一些特定的注意事项。</li>
</ul>

<table>
  <tr>
    <th>主系统</th>
    <th>描述</th>
  </tr>
  <tr>
    <td>Salesforce</td>
    <td>远程系统会存储 Salesforce 记录 ID 或记录中的一些其他唯一替代密钥。</td>
  </tr>
  <tr>
    <td>远程系统</td>
    <td>对远程进程的调用会从应用程序中返回唯一密钥，Salesforce 将该密钥值存储在唯一记录字段中。</td>
  </tr>
</table>

**复杂集成**

在某些情况下，此模式规定的解决方案可能需要实施复杂的集成场景。这些场景通常使用中间件解决。

<ul>
  <li>对多个系统的呼叫及其结果的聚合</li>
  <li>入站和出站消息的转换</li>
  <li>保持对多个系统的调用之间的事务完整性</li>
  <li>Salesforce 与外部系统之间的其他流程编排活动</li>
</ul>

**管理限制**

不同的适配器有不同的限制。有关更多详细信息，请查看 <a href="https://help.salesforce.com/s/articleView?id=platform_connect_general_limits.htm&type=5">Salesforce Connect 一般限制</a>。

**中间件功能**

下表强调了参与此模式的中间件系统的理想属性。

<table>
  <tr>
    <th>房地产</th>
    <th>强制</th>
    <th>理想</th>
    <th>不需要</th>
  </tr>
  <tr>
    <td>事件处理</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
    <tr>
    <td>协议转换</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
    <tr>
    <td>翻译和转换</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>排队和缓冲</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>同步传输协议</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>异步传输协议</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>中介路由</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>流程编排和服务编排</td>
    <td align="center"></td>
    <td align="center">X</td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>事务性（加密、签名、可靠交付、事务管理）</td>
    <td align="center">X</td>
    <td align="center"></td>
    <td align="center"></td>
  </tr>
  <tr>
    <td>路由</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
  <tr>
    <td>提取、转换和加载</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
  <tr>
    <td>长时间投票</td>
    <td align="center"></td>
    <td align="center"></td>
    <td align="center">X</td>
  </tr>
</table>

**外部对象关系**

外部对象支持标准查找关系，即使用 18 个字符的 Salesforce 记录 ID 关联相关记录。但是，存储在您的 Salesforce 组织外部的数据通常不包含这些记录 ID。因此，两种特殊类型的查找关系对外部对象可用：外部查找和间接查找。

此表总结了对外部对象可用的关系类型。

<table>
  <tr>
    <th>关系</th>
    <th>允许的子对象</th>
    <th>允许的父对象</th>
    <th>匹配记录的父字段</th>
  </tr>
  <tr>
    <td>查找</td>
    <td>标准、自定义、外部</td>
    <td>标准，自定义</td>
    <td>18 个字符的 Salesforce 记录 ID</td>
  </tr>
  <tr>
    <td>外部查找</td>
    <td>标准、自定义、外部</td>
    <td>外部</td>
    <td>外部 ID 标准字段</td>
  </tr>
  <tr>
    <td>间接查找</td>
    <td>外部</td>
    <td>标准，自定义</td>
    <td>选择具有外部 ID 和唯一属性的自定义字段</td>
  </tr>
</table>

_Salesforce Connect 的高数据量注意事项 -- Odata 2.0 和 4.0 适配器_

如果贵组织在访问外部对象时达到速率限制，请考虑在关联的外部数据源上选择高数据量选项。这样做会绕过大多数流量限制，但有一些特殊行为和限制。有关更多信息,请查看 <a href="https://help.salesforce.com/s/articleView?id=platform.odata_considerations_high_data_volume.htm&type=5">Salesforce Connect 高数据量注意事项</a>

_Salesforce Connect 的客户端驱动和服务器驱动分页 — Odata 2.0 和 4.0 适配器_

通常，Salesforce Connect 对外部数据的查询会包含大量结果集，这些结果集会分为较小的批次或页面。您可以决定分页行为是由外部系统（服务器驱动）还是由 Salesforce Connect 的 Odata 2.0 或 4.0 适配器（客户端驱动）控制。外部数据源上的服务器驱动的分页字段指定是使用客户端驱动的分页还是服务器驱动的分页。如果您在外部数据源上启用服务器驱动的分页，Salesforce 会忽略请求的页面大小，包括默认的 500 行 queryMore() 批处理大小。外部系统返回的页面决定批次，但每页不能超过 2000 行。但是，Salesforce Connect 的 Odata 适配器的限制仍然适用。

**示例**

一家制造公司使用 Salesforce 来管理客户个案。客户服务客服人员希望从后台 ERP 系统访问实时订单信息，以获取客户的 360 视图，而无需在 ERP 中学习和手动运行报表。

实施此模式规定的解决方案，您应：

<ul>
  <li>使用 Odata 端点配置外部数据源。您的远程应用程序可能包括对 Odata 的本地支持。对于其他应用程序，Dell Boomi、Informatica、Jitterbit、MuleSoft 和 Progress Software 等主要集成供应商已在 Salesforce Connect 上与 Salesforce 合作构建适配器。</li>
  <li>直接或通过中间件解决方案，在 Odata 端点点 Salesforce Connect。</li>
  <li>将外部数据库表与 Salesforce 中的外部对象同步。在用户访问包含这些外部对象数据的页面时，Salesforce Connect 会对后端应用程序进行实时标注。</li>
</ul>

## 附录 A：资源

**开发人员文档**

- [_Salesforce 帮助：授予集成用户仅 API 访问权限_](https://help.salesforce.com/s/articleView?id=platform.integration_user.htm&type=5)

- [_SOAP API 开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_quickstart_intro.htm)

- [_REST API 开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm)

- [_串流 API 开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/intro_stream.htm)

- [_批量 API 2.0 和批量 API 开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/asynch_api_intro.htm)

- [_Apex 开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm)

- [_SOQL 和 SOSL 参考_](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_sosl_intro.htm)

- [_Salesforce 开发人员限制和分配快速参考_](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_overview.htm)

- [_平台事件开发人员指南_](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm)

- [_Apex 开发人员指南:Salesforce Connect_](https://help.salesforce.com/s/articleView?id=platform.platform_connect_about.htm&type=5)

**Trailhead**

- [_大数据量_](https://trailhead.salesforce.com/content/learn/modules/large-data-volumes)

- [_平台事件基本知识_](https://trailhead.salesforce.com/content/learn/modules/platform_events_basics)

- [_变更数据捕获基本知识_](https://trailhead.salesforce.com/content/learn/modules/change-data-capture)

- [_快速入门：Salesforce Connect_](https://trailhead.salesforce.com/content/learn/projects/quickstart-lightning-connect)

## 附录 B：安全注意事项

要成为企业产品组合的有效成员，必须创建所有应用程序并与相关安全机制集成。现代 IT 策略结合了内部部署和基于云的服务。

虽然集成云到云服务通常侧重于 Web 服务和相关的授权，但连接本地和云服务通常会增加复杂性。本节介绍安全工具、技术和特定于 Salesforce 的注意事项。

**反向代理服务器**

反向代理是位于 Web 服务器前面的服务器，并将客户端（例如 Web 浏览器）请求转发到这些 Web 服务器。反向代理通常用于帮助提高安全性、性能和可靠性。

这是一种代理服务器，代表客户端从一个或多个服务器检索资源。然后，这些资源被返回到客户端，就像它们来自代理服务器本身一样。与前向代理不同，前向代理是关联客户端联系任何服务器的中介，反向代理是关联服务器被任何客户端联系的中介。

在 Salesforce 实施中，此类服务通常通过外部网关产品提供。例如，可以使用 Apache HTTP、lighttpd 和 nginix 等开源选项。商业产品包括 IBM WebSeal 和 Computer Associates SiteMinder。这些产品可以轻松配置为代表内部请求者代理和管理所有出站 Salesforce 请求。

**加密**

一些企业要求在内部部署和基于云的应用程序组合之间加密选定的交易或数据字段。如果贵组织必须遵守其他合规要求，您可以实施替代方案，包括：

- 本地商业加密网关服务，包括 Salesforce 自己的 CipherCloud、IBM DataPower、计算机关联。对于每个解决方案，加密引擎或网关在事务边界处通过发送和接收加密负载来调用，或者在 HTTP(S) 请求执行之前加密或解密特定数据字段时调用。

- 基于云的选项，例如 Salesforce Shield 平台加密。Shield Platform Encryption 为您的数据提供了全新的安全层，同时保留了关键的平台功能。您选择的数据使用高级密钥派生系统进行静态加密。您可以比以往更安全地保护您的数据。有关更多信息，请参考 Salesforce 在线帮助。

**专用 WS-\* 协议支持**

为了满足安全协议的要求（例如 WS-\*），我们建议使用以下替代方案。

- Security/XML 网关 — 将 WS-Security 凭据（IBM WebSeal 或 Datapower、Layer7、TIBCO 等）注入事务流本身。此方法不需要更改应用程序级 Web 服务或 Salesforce 的 Web 服务调用。您也可以在 Salesforce 安装中重复使用此方法。但是，它需要额外的设计、配置、测试和维护来管理对现有安全网关方法的适当 WS-Security 注入。

- 传输级加密 — 使用双向 SSL 和 IP 限制加密通信渠道。虽然这种方法本身并不直接实施 WS-\* 协议，但它保护了本地应用程序和 Salesforce 之间的通信渠道，而无需传递用户名和密码。它还不需要更改 Salesforce 生成的类。但可能需要一些内部 Web 服务修改（在应用程序本身或中间件/ESB 层）。

- Salesforce 自定义开发 — 通过 WSDL2Apex 实用程序将 WS-Security 标题添加到出站 SOAP 请求。这将从用于调用内部服务的 WSDL 文件生成类似 Java 的 Apex 类。虽然这种方法不需要更改后端 Web 服务或 DMZ 中的其他组件，但它确实需要：

  - 增加构建和测试工作量
  - 手动编码 WS-Security 属性的相对复杂和手动过程（包括 Apex 代码中的 XML 序列化）
  - 更高的长期维护工作量

**备注**:不推荐最后一个选项，因为它很复杂，并且这种集成需要根据对 Salesforce 的定期更新进行定期审查。

**其他安全注意事项**

- 命名凭据：命名凭据旨在保护和简化外部系统的经过身份验证的 API 标注，它在一个定义中指定标注端点的 URL 及其所需的身份验证参数。要简化 Apex 代码并简化经过身份验证的标注的设置，请将命名凭据指定为标注端点。有关更多详细信息，请查看[此处](https://help.salesforce.com/s/articleView?id=xcloud.named_credentials_about.htm&type=5)。

- OAUTH 2.0：OAuth 2.0 是一个行业标准的授权框架，允许用户向第三方应用程序授予对其受保护资源的有限访问权限，而无需共享他们的凭据（例如密码）。用户批准访问令牌请求，然后应用程序使用该请求从资源服务器访问用户数据，而不是直接进行密码交换。该过程将客户端应用程序与用户的身份和密码分开，通过提供临时的特定于范围的“密钥”来访问资源，从而提高了安全性。有关更多信息，请查看[此处](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_flows.htm&type=5)。

- 专用连接：当您将您的 Salesforce 组织与托管在第三方云服务上的应用程序集成时，能够安全地发送和接收 HTTP/s 流量至关重要。通过专用连接，通过在 Salesforce 组织和 AWS 虚拟私有云 (VPC) 之间设置完全受管的网络连接，提高 Amazon Web Services (AWS) 集成的安全性。然后，通过连接而不是公共互联网路由您的跨云流量，以减少对外部安全威胁的暴露。专用连接可通过名为 AWS PrivateLink 的功能与 AWS 合作使用。专用连接是双向的：您可以发起入站和出站流量。通过入站连接，您可以使用标准 API 将流量发送到 Salesforce。通过出站连接，您可以通过 Apex 标注、外部服务和外部对象等功能将流量从 Salesforce 发送出去。有关 VPC 的更多信息，请[在此处](https://help.salesforce.com/s/articleView?id=xcloud.private_connect_overview.htm&type=5)。

## 附录 C：事件驱动的架构

具有平台事件、变更数据捕获 (CDC) 和发布 /订阅 API 的 Salesforce 事件总线使企业能够创建事件驱动的样式架构 (EDA)。

EDA 将事件消息使用者（订阅者）与事件消息生产者（发布者）分离开来，允许更大的规模和灵活性。本文档涵盖了作为现有模式结构一部分的特定模式，用于比较和对比相关的替代方案或选项。但是，全面了解事件驱动的架构，以及模式如何相互作用，可以帮助您根据自己的需求选择合适的模式。

## 关于作者

Khalid Mohammed 是 Salesforce 专业服务中的杰出架构师领导者。自 2015 年加入 Salesforce 以来，他在 Salesforce 任职之前，充分利用了自己在企业应用程序和架构方面的广泛专业知识，经历了多次客户转换。Khalid 领导交付架构委员会，也是公认的认证技术架构师领导者。

Gulal Kumar 是 Salesforce 的软件工程架构师，专注于数据和集成架构。他在集成和 API、现代化计划、安全和 AIML 计划方面拥有超过 20 年的经验，拥有丰富的专业知识。Gulal 一直致力于推进业务转型计划，增强安全性和弹性，促进架构卓越性，并领导各个领域的 AIML 计划。

Sushant 是 Salesforce 的技术架构师，专门从事 Salesforce 平台的解决方案架构和端到端交付。凭借在平台治理、应用程序开发、集成和 DevOps 方面的深厚专业知识，他领导了多个行业的客户转型计划。Sushant 致力于提高交付卓越性和可扩展性架构成果。
