发布网友 发布时间:2022-03-27 10:14
共1个回答
热心网友 时间:2022-03-27 11:44
本真REST当然是对面向资源架构的一种实现,而并非一种纯粹的技术决策。所以当讨论本真REST时,真正应该讨论的问题是:其基础支撑——面向资源的架构(ROA)——是否真的适合作为你的SOA实现。
为正确评估该问题,让我们首先回想一下SOA的架构风格,它是基于企业业务架构的功能性分解,并且引入了两个高层次的抽象:企业业务服务和业务流程。企业业务服务代表的是现有IT能力(和企业的业务功能相一致)。业务流程编排业务服务,并定义业务的整体功能。
而REST是一组被称之为面向资源架构(ROA)的架构准则。ROA构建在资源这一概念之上;每个资源都是一个能够直接访问的分布式组件,可通过一个标准的、通用的接口来处理。所以,面向资源的架构(ROA)其最根本的还是一种基于资源的分解[3]。
为了评估本真REST是否适用于面向SOA的实现,我们真正需要回答的问题是,“服务和资源之间到底是什么关系?”
服务 vs. 资源
何为服务?
在最简单的情况下,服务可以被定义为一个自包含、开发、可部署、可管理和可维护的软件实现,它从整体上为企业提供特定的与业务相关的功能,并且在设计上是“可集成的”。“服务”可以通过动词(verb)来定义(例如,“验证客户信用积分”,这描述了服务实现的业务功能)。
服务并不是某个编程结构或一组APIs,而是一个用于实现企业解决方案的架构(设计单元、实现以及维护)和部署构件。服务接口(尤其对某个给定的服务而言)定义服务功能,并且可由多种方式实现。存在两种基本的定义服务接口的方法——RPC风格和消息(messaging)风格,RPC风格实现使用服务调用语义并且通过服务接口中的一组参数来定义。而消息风格的服务接口被有效地固定(本质上只需要进行“执行”操作)使用XML文档作为输入和输出(这和GoF设计模式非常相似)。在这种情况下,服务语义是由输入和输出消息的语义来确定[4]。
过去,服务通常被定义为一组方法的集合,但正如参考文献[2]中解释的那样,这些方法彼此相互[5],但作为整体它们共享同一个命名空间,这样简化了对服务的管理。
何为资源?
在最简单的情况下,资源可以被定义为一个可直接访问的、开发的、可部署的、可管理的和可维护的软件构件,它支持特定的数据。资源可以通过名词(noun)来定义,比如“医生的预约”就描述了资源提供的数据。某一资源也可以和其他资源相关联并为它们提供引用(链接)。实际上,一个资源就类似于一个对象[6],不过它是带有预定义(CRUD)接口语义的对象。
REST中的语义基于HTTP操作集,如下所示[5]:
createResource——创建一个新的资源(以及相应的唯一标示)– PUT
getResourceRepresentation——获取资源信息– GET
deleteResource ——删除资源(可选地包括相关联的资源)– DELETE(只是引用的资源),POST(当需要删除相关联的资源时使用)
modifyResource——更改资源— POST
getMetaInforatmion——取得资源元数据信息—HEAD
资源通过两部分定义:资源URL和资源所提供的所有操作上定义的输入/输出参数[7]。这和服务不同,服务的方法之间是完全,并且能够以端点(endpoints)的方式部署,而资源上的方法遵循OO语义,这意味着所有的方法(除createResource以外)都必须依附于底层的某个资源(同一个URL)。
资源和服务之间的根本差异
基于上述对资源和服务的定义,凭直觉它们显然是不同的。我们先继续深究这些差别,然后再讨论它们是如何对最终架构产生影响的。
正如文献[6]中描述的:
REST不仅不是面向服务的,相反,面向服务和REST风马牛不相及
文献[7]中进一步阐明了二者之间的区别:
如果把WS-*比作是互联网世界的RPC,那么REST就是互联网世界的数据库管理系统(DBMS)……传统的基于SOA的集成表现了不同软件构件之间通过各种过程或方法进行交互。REST有效地将每个软件构件看作一组数据库表,而这些构件之间使用SELECT, INSERT, UPDATE和DELETE来通信。(或如你所想的使用GET, PUT, POST, DELETE)。那业务逻辑放在哪里呢?在存储过程中?不太对,其实在触发器中。
这里我们用J2EE打个稍微不太恰当的比方。我们把服务想象成无状态会话bean,而资源想象成实体bean。
服务(或会话beans)作为控制器控制执行所需的操作,不管底层是哪个资源。打个比方,某个支出账户服务可能会用到账户ID、支出金额和支出所需账户。这样的服务可以支出任何现有账户。
资源(或实体bean)充当数据访问机制,其面对给定数据类型的某一实例。比如,为了从某一账户支出,需要先找到这一账户相关的信息,然后才能更新它,从而向所需账户进行支出。另外提醒一下,与能实现任意所需的方法的实体bean不同的是,一个REST资源只有一个更改资源的方法。这意味着真实的业务操作——支出——只能编码成消息请求的一部分。