使用RESTful服务和应用程序API实现SOA?

时间:2018-01-18 17:32:40

标签: rest api architecture soa

目前我们有一个巨大的API供我们的后台,我们的前端以及我们的公共API使用。

这引起了很多麻烦,因为在构建新端点时,我发现代码中有很多特定于应用程序的逻辑,我不一定要在我的端点中包含这些逻辑。例如,创建用户的代码可能包含发送欢迎电子邮件的代码,但由于后台端点不需要,我将需要添加没有该逻辑的新端点。

我正在考虑使用大型重构来将我们的代码库分解为许多较小的高度特定的服务API,然后在这些API之上构建一组小型应用程序API。

因此,例如,创建新用户的应用程序端点可能会在重构后执行类似的操作:

customerService.createCustomer();
paymentService.chargeCard();
emailService.sendWelcomeEmail();

应用程序和服务API将是完全独立的代码库(可能是每个服务单独的代码库),它们也可以使用不同的语言构建。它们只会通过REST API调用进行交互。它们将位于同一个本地网络上,因此延迟不应该是一个大问题。

这是个坏主意吗?我以前从未见过/曾经在将两者分开的代码库上工作,所以也许有更好的架构来实现我正在寻找的灵活性和可维护性?

建议,链接或评论都将受到赞赏。

3 个答案:

答案 0 :(得分:2)

您制作多个明确定义的服务的想法是合理的,实际上它是解决此问题的最佳方式。采用纯粹的微服务方式,但看起来很流行,经常被证明是一种过度杀伤力。这就是为什么我只是正确地重新设计现有的API /服务,并遵循以下坚实和合理的SOA设计原则。良好的资源可以在serviceorientation.comsoapatterns.org找到。我一直在他的职业生涯中使用它们作为参考。

考虑您需要哪些类型的服务

Service types and Layers(来自serviceorientation.com的图片)

  • 实体服务通常是您的客户,付款服务 - 例如服务以您域中的实体为中心。它们应该与业务无关,并且能够在所有场景中重用。如果足够满足他们的需求,客户有时可以直接调用它们。它们可以由任务服务调用。
  • 实用程序服务包含您可能在其他服务中重用的逻辑,但通常不会被客户端直接调用。相反,他们将被任务和实体服务调用。一个例子可能是音译服务。
  • 任务服务将实体和公用服务组合并重用为有意义的任务。大多数情况下,他们不是那种不可知论者,他们确实实施了一些特定的业务逻辑。他们拥有有意义的业务运营,而且客户大多都会这样做。

重新设计时应遵循的原则

我强烈建议您进行over this cheat sheet并确保在重新设计时确保所有内容都已涵盖。这是很好的帮助。

一般来说,你应该确保:

  1. 每项服务都有共同背景,并遵循关注点分离原则。例如。 Clients服务仅适用于与客户相关的操作等。

  2. 每个实体和公用服务都与业务无关且足够基本。因此,它可以在多个场景和上下文中重用,而不会被更改。合同必须简单 - CRUD和只有在大多数使用场景中有意义的常见操作。

  3. 服务遵循通用数据模型 - 确保您使用的所有数据结构在所有服务中统一使用,以防止将来需要集成工作并促进服务组合供客户利用。如果您需要接收其他服务返回的客户,则应该在不需要转换的情况下进行此操作

  4. 好的,但是在哪里放置非不可知逻辑?

    现在,只要您需要复杂的业务功能,就可以有多种选项来抽象业务逻辑。这取决于您的情况,您将选择什么:

    • 将逻辑留给所有客户。让他们结合您的简化服务
    • 如果存在通常在多个应用程序中实现的业务逻辑,并且可能会大量重用,则可以实现重用多个现有底层服务并公开逻辑的组合服务。 / LI>

    服务可组合性。对多个API的担忧会调用通信开销。

    嗯,这是一个古老的问题 - 当你可能会创建一些通信开销时,你应该进行多次API调用吗?答案是 - 这取决于您的方案的复杂程度,您期望的重用次数以及您希望的灵活性。速度也很关键吗?到什么程度?但是,在面向服务的体系结构中,这是一种非常常见的方法 - 重用现有服务并根据需要将它们组合到新配置中。是的,它确实增加了一些开销,但我已经看到在非常复杂的环境中实现,例如Telecoms,由于使用ESB解决方案,消息队列等,与优点相比,开销可以忽略不计。这是一种常见的架构方法(来自serviceorientation.com的图片):

    Composing Web Services to Solve a Bigger Problem

    强制性遗留重构单挑

    通常情况下,更改现有多个客户端系统的既定合同是一项混乱的业务,很可能会导致大量的重构,并且需要寻找堆栈中的堆栈功能(可能在某些地方)遗留代码。业务逻辑可能分散在各处。因此,请确保您已做好准备并拥有控制权,时间和意愿来领导这场战斗。

    希望这有帮助

答案 1 :(得分:1)

  

这是个坏主意吗?

不,但这是一个很大的整体问题,能够提供非常具体的建议。

我想将其分为3个方面:

  • 方法
  • 设计
  • 技术

向后工作,技术是最终和最具体的部分,完全取决于您当前的环境(平台,技能),并且(希望)合理不言而喻你其他事情正在进行中。

您在上面概述的设计似乎是一个很好的最终状态 - 拥有多个特定的,专注的API,每个API都有自己的责任。同样,设计的细节将取决于您和您的组织的技能,以及您拥有的现有平台。例如。如果您已经在使用TIBCO(例如)并投入大量资金(许可证,平台,工具,人员),那么利用他们发布的一些模式/设计/模板是有意义的;但(可能)如果你还没有TIBCO暴露,那就不行了。

在摘要中,REST API服务似乎是一个很好的起点 - 系统的各个层面都有很多工具和平台用于安全性,部署,监控,可扩展性等。如果您是NGINX用户,他们关于如何执行此操作还有很多(平台无关的)想法NGINX blog,包括对可伸缩性和性能的一些聪明的想法。如果您更具冒险精神,拥有一支聪明,热切的团队,那么请看一下事件驱动的架构 - 请参阅this

方法(或流程)关键事项。最终,这是一个重构,尽管您对"一个大型重构"确实吓到了我 - 就这样,听起来你正在谈论一个大爆炸的变化并称之为重构。也许这只是语言,但我脑子里的想法是"一个巨大的API'进入多个,特定的,专注的API(通过重构架构)"。一个开始的地方是Martin Fowler,而本书是关于重构软件的,原则和方法是相同的,只是在更高层次。实际上,他只讨论了here

IBM谈论refactoring to microservices并且让它在一个步骤中变得容易,但它永远不会(在实验室之外)。

您有一个现有的API,为多个内部和外部客户端提供服务。我建议您希望为这些客户端保持此界面的可靠性 - 将实施的重构与联络和协调外部系统/组的其他问题分开。我的高级启动方法是:

  • 在API上识别少量(3-7)个相关方法
    • 理想情况下,如果使用这些方法需要进行重大的,有限范围的更改,这很好 - 代码更改的商业价值
  • 专门为这些方法设计/指定一个新的独立API
    • 首先,克隆现有的模型/命名/样式
  • 为这些代码编写新服务
    • 使用适当的自动化CI / CD测试和部署实践
    • 与相关监控
  • 修改现有API以调用这些方法重定向以调用新服务
    • 可能有一个运行时切换来在旧实现和新实现之间进行切换
  • 从代码库中删除旧实现
  • 沿途捕捉问题,假设和问题
    • 第一遍将涉及大量了解哪些有效,哪些无效。
  • 然后重复这个过程&结束,每次都进行改进。

在未来的某个时刻,由于其他业务驱动的需求,适当时,发布到后端,前端和/或公共客户端的API可能会发生变化,但这是一个完全不同的项目。

正如您所看到的,如果API很大(1,000种方法=> 140次发布),这是一个数月的过程,并且具有合理频繁的发布计划非常重要。并且可能没有值得改进的代码可靠且永不改变,因此现有API的(可能)大部分可能仍然存在,只是由新API包装。

其他考虑因素:

我可以提供的最大 4条建议可能是:

  • 认为重构:不会影响功能
  • 认为敏捷:增值是有价值的,可测试的,可实现的
  • 思考连续性:对你将(最终)到达的地方有一个愿景,然后不断地完成这个过程
    • 脚本&从代码,文档,测试,部署,监控中自动化流程......
    • 每次改进它!
  • 你有一个可行的应用程序/ API - 让它保持正常运行!
    • 这始终是第一要务(你只需要开展维修时间/预算)

答案 2 :(得分:1)

根本不是一个坏主意。

您还在寻找什么是微服务。因此,问题就在于如何将您的系统分解为定义明确的服务。

我们使用Domain Driven Design Arch。将我们的系统分解为微服务和lagom框架,它允许每个服务都是差异的。代码库和事件驱动的arch。微服务之间。

现在让我们在低级别查看您的问题:您说服务包含创建用户和发送电子邮件等代码以及仅创建用户的代码,并且可能还有其他代码。

首先,我们需要了解您正在编写的代码类型:

  1. 域对象逻辑(例如:用户对象) - 哪些参数有效且全部 - 这应该独立于服务端点,应该封装在一个类用户类中,我们称它为域驱动设计术语中的聚合
  2. 商业反应 - 就像用户创建一样发送电子邮件 - 使用事件驱动的arch。这些类型的逻辑分为流程管理器或sagas,大多数情况下都可以有条件地工作,就像外部创建的用户发送邮件一样,内部创建的用户通过事件中的额外数据发送电子邮件
  3. 另外,您目前的做法是,如何处理跨服务的交易???