使用Heroku计算扩展流程:事件驱动模式

2020-12-12 17:48:22

实践证明,事件驱动的应用程序体系结构对于使用松散耦合的服务(通过交换异步事件进行交互)来实施企业解决方案非常有效。 Salesforce通过平台事件和变更数据捕获(CDC)事件以及触发器和Apex标注启用事件驱动的体系结构(EDA),这使Salesforce平台成为构建所有数字客户体验的绝佳方法。这篇文章是该系列文章的第一篇,涵盖各种EDA模式,使用它们的注意事项以及在Salesforce平台上部署的示例。

早在4月,Frank Caron就在博客中描述了EDA的强大功能。在其中,他介绍了事件驱动的方法以及松散耦合的服务交互的好处。他主要关注事件触发跨平台服务的操作的用例,以及如何整合第三方外部服务如何极大地扩展使用声明性低代码工具(如Salesforce Flow)开发的应用程序的功能。

流程具有访问第三方服务所具有的强大功能,而当您自己的自定义应用程序(在Salesforce平台上运行自己的业务逻辑)成为流程的一部分时,其功能将更加强大。

基于API的事件驱动设计是一种开发,经常需要团队中不同成员之间的协作。具有领域专业知识且熟悉业务需求的低代码构建者可以构建流程。程序员通常是开发实现业务逻辑的后端服务所必需的。企业架构师也可能会参与设计服务API。

无论您是如何组织的,都需要使用API​​公开您的服务,并使它们能够产生和使用事件。 Salesforce平台通过Salesforce事件总线,Salesforce函数和Streaming API以及对外部服务的OpenAPI规范的支持来实现此目的。

Salesforce平台上的Heroku功能包括事件流,关系数据存储以及与弹性计算无缝集成的键值缓存。这些功能与部署自动化和卓越的手动操作相结合,使您的开发人员可以完全专注于交付独特的业务需求。与Salesforce其余部分的无缝集成使您在Heroku上部署的应用程序成为完整,引人注目的,经济,安全和成功的解决方案的基础。

这篇文章重点介绍如何使用Heroku计算扩展流量。具体而言,如何将Heroku应用程序公开为外部服务,以及如何使用Flow Builder作为低代码开发环境通过流安全地访问它们。随后的帖子将扩展这个想法,包括Heroku应用程序与其余Salesforce Platform之间的事件驱动的交互,以及基于Salesforce Platform的EDA如何解决我们在许多客户中看到的常见挑战的其他示例,包括:

Salesforce外部服务是从流访问第三方服务的好方法。您只需要服务的OpenAPI规范架构(OAS架构),就可以开始使用了。这里有一些很好的示例,这些示例说明了如何注册您的外部服务,并在此处提供了有关如何生成Apex客户端和浏览架构的更详细的示例。

但是,如果您要将自定义业务逻辑合并到流应用程序中怎么办?如果您想使用具有完整编程语义的命令式模型扩展和补充流程的声明式编程模型,该怎么办?如果您想让您的应用程序可供其他组织的开发人员使用,或者可能作为基于Lightning Web Components的应用程序后面的独立服务进行访问,该怎么办?

这种服务部署通常需要进行平台外开发,从而带来了满足业务关键应用程序的可伸缩性,可用性和可靠性要求所带来的所有复杂性和运营开销。

以下步骤向您展示了如何在Salesforce平台上使用Heroku部署自己的应用程序,而无需承担任何操作开销。我们将通过一个示例演示如何将自定义业务逻辑构建和部署到您自己的服务中,并以流方式对其进行访问。部署将通过Heroku应用程序进行,该应用程序具有编写自己的代码的功能和灵活性,而不必担心生产应用程序部署或DevOps工具链的操作负担。

这种方法在程序员和低代码构建者共同部署新应用的情况下效果很好。团队首先就应用程序需要做什么进行协作,并定义流可以访问的API。 API设计完成后,此规范即成为两个团队之间的合同。随着双方的进步,他们会不断迭代,完善设计并最终交付应用程序。该示例中使用的所有代码都可以在GitHub上找到,因此您可以自己尝试一下。

注意:Apex是自定义Salesforce的好方法,但是有时候独立应用程序可能是更好的选择。如果您的团队喜欢使用Python,Node或其他某种编程语言,或者您已经有一个在本地或云中运行的应用程序,并且想要在Salesforce平台的安全范围内全部运行,则可以使用独立的Heroku应用程序要走的路。

该示例应用程序是一个在线购物站点,允许用户登录,浏览产品并进行购买。我们将在许多文章中描述构建此应用程序的过程,但是对于第一部分,我们将简单地构建一个流程和外部服务,以列出产品并更新Salesforce中的库存。对于API,我们使用的是Swagger Hub上的示例API。有多种工具和系统可以执行此操作,包括MuleSoft Anypoint Platform API Designer。但是,对于这个示例,我们使用这个简单的购物车规范来引导API设计并提供用于开发的初始应用程序存根。

根据API规范,API门户可以生成服务器端应用程序存根,以快速启动应用程序开发。在此示例中,我们下载了node.js API存根作为API和应用程序开发的起点。我们还修改了代码,使其可以通过添加Procfile并更改端口配置在Heroku上运行。如果您想自己尝试,可以部署到Heroku,或单击GitHub页面上的Deploy to Heroku按钮。

首先,查看该应用程序的初始API规范。这些API文档是通过在Heroku上部署应用程序存根提供的。实际的YAML规范(我们将在本文后面的内容中进行修改)也包含在存储库中。

如您在规范中所看到的,每种方法都有定义,这些定义指定需要哪些参数以及响应有效载荷的外观。由于这是有效的OpenAPI规范,因此我们可以按照外部服务入门中的说明将此API注册为外部服务。

该流需要Salesforce中的命名凭证才能访问外部服务。对于应用程序如何使用命名凭据,Salesforce提供了许多替代方法,包括每用户凭据,可以帮助您跟踪和控制访问。不过,在此示例中,我们将使用基本的HTTP身份验证对所有流访问使用一次登录。

您可以在存储库中包含的应用程序中找到实现此方法的代码。

通过Salesforce JWT帐户令牌授权对组织的应用访问,并在SFAuthService.js中的应用中实现:

'使用strict' const jwt = require(' salesforce-jwt-bearer-token-flow'); const jsforce = require(' jsforce'); require( ' dotenv')。config(); const {SF_CONSUMER_KEY,SF_USERNAME,SF_LOGIN_URL} = process.env;让SF_PRIVATE_KEY = process.env.SF_PRIVATE_KEY; if(!SF_PRIVATE_KEY){SF_PRIVATE_KEY = require(' fs')。readFileSync(' private.pem')。toString(' utf8');} exports.getSalesforceConnection = function(){return new Promise(function(resolve,reject ){jwt.getToken({iss:SF_CONSUMER_KEY,sub:SF_USERNAME,aud:SF_LOGIN_URL,privateKey:SF_PRIVATE_KEY},(err,tokenResponse)=> {如果(tokenResponse){让conn = new jsforce.Connection({ .instance_url,accessToken:tokenResponse.access_token}); resolve(conn);} else {reject('对Salesforce的身份验证失败');}});});};

私钥在Heroku中配置为配置变量,并在部署应用程序时安装。

就像对任何外部服务一样,可以轻松地将ShoppingService外部服务的各个方法添加到流中。我们在这里添加了“获取产品”和“获取订单”方法,如下面的Flow Builder中所示。但是,由于Flow Builder只能使用API​​规范注册外部服务方法,因此它们只是对我们仍然需要构建的存根方法的引用。我们将在本文后面为他们编程。

对于已经注册了外部服务的人来说,这些都是熟悉的步骤,但是如果您想要更多有关如何执行此操作的详细信息,请查阅“外部服务入门”入门指南。

有了适当的授权和定义的方法,我们现在可以按照满足公司特定需求的方式来构建外部服务。为此,我们需要实现每个API方法。

为了说明这一点,这里是由Get Order方法的API删除的Node函数。在这里实现您的业务逻辑。

对于每种API方法,我们已经实现了一些简单的逻辑,这些逻辑将用于测试与流程的交互。例如,下面是获取所有订单列表的代码:

/ ** *获取用户所有订单的列表* *类型String json或xml * pOSTDATA List在数据库中创建新员工(可选)*返回列表** / exports.typePost_orderPOST = function(type,pOSTDATA){返回新Promise(function(resolve,reject){var examples = {}; examples [' application / json'] = [{" Item Total Price":1998.0," Order Item ID":643,"订单ID":298,"总订单价格":3996.0},{"项目总价"#:1998.0,&#34 ; Order Item ID":643," Order ID":298," Total Order Price":3996.0}]; if(Object.keys(examples..length> 0 ){resolve(examples [Object.keys(examples)[0]]);} else {resolve();}});}

现在,我们在每种方法中都有一些简单的逻辑可以执行,我们可以构建一个简单的流,该流使用命名凭证登录,访问外部服务并返回产品数据。

运行此流程将显示存根应用程序中的产品数据。在此处成功显示产品数据表示该流程已能够成功登录到应用程序,调用Get Product方法并获得正确的响应。

因此,既然我们已经定义了基本流程并访问了该应用程序,我们就可以使用该应用程序执行其所需操作所需的新方法来完善该API。

假设该应用程序具有最新的产品库存数据,并且我们希望使用该数据用当前的库存数量更新Salesforce中的Product对象。为此,应用程序将需要能够访问Salesforce并更新Product对象。

为此,流程需要向“获取库存”方法发出请求。但是该方法尚不存在。但是,我们可以修改API以包括所需的任何新方法。在这里,我们的团队一起确定应用程序中需要什么流程以及需要什么方法。

经过讨论,我们确定单个“获取库存”方法将满足要求。因此,现在我们更新API规范以包括一个新方法:

/ {type} / get_inventory /:get:标签:-"内部通话"说明:"获取库存" operationId:" typeGet_inventoryGET"消耗:-" application / json"产生:-" application / json" -" application / xml"参数:-名称:"类型"在:"路径"说明:" json或xml"必需:正确类型:" string" -名称:" product_id"在:"查询"说明:"产品ID"必需:真实类型:" integer"回复:" 200&#34 ;:说明:" OK"模式:类型:" array"项目:$ ref:"#/ definitions / Inventory"安全性:-基本:[]

使用此更新的API,我们可以更新外部服务,以便可以在流程中使用它。

借助更新的API规范,我们还可以自动生成存根方法。通过空存根方法,我们可以使用必要的逻辑来完成功能,以直接访问Salesforce并更新Product对象。请注意,它使用上面的SFAuthService.js代码和API令牌来访问组织数据。

现在可以使用这种清单方法,我们可以使用一个简单的流程来检查操作,该流程在平台事件上触发并更新Product对象。当我们运行此测试流程时,它将更新组织中的iPhone产品对象。

流程如何以及何时需要更新产品库存将取决于实际的业务需求。但是,可以使用平台事件来触发更新对象的流程。该流可以通过调用Get Inventory方法来响应任何平台事件。

这篇文章中描述的过程可以继续进行,直到流程和应用程序API融合为稳定的设计为止。一旦稳定,我们的程序员和低代码构建者可以独立完成工作以完成应用程序。流程设计者可以构建围绕流程的所有决策逻辑,并为用户建立交互界面。

程序员可以独立于流程设计人员而独立地对存根应用程序中的每个方法进行编码,以实现业务逻辑。

我们刚刚开始构建此应用并将其作为外部服务运行。但是,在本文中,您已经看到了每个开发周期的基本步骤:定义API,注册流程可以调用的方法,构建存根应用程序以及授权对流程,应用程序的访问以及平台事件触发器。

本系列的后续文章将采用这些基本元素和方法,以扩展流程以通过用户界面元素执行应用程序中包含的业务逻辑,以实现完全在Salesforce平台上运行的完整流程自动化解决方案。 要了解更多信息,请参见Heroku Enterprise Basics Trailhead模块和Flow Basics Trailhead模块。 请在Twitter上与@SalesforceArchs分享您的反馈。