这是一个值得回答的问题,而简短的回答并不公正.忘记大多数人可能比REST更熟悉SOAP的事实,我认为这里有几个关键点:
首先,我建议在任何适合自然的地方使用REST.如果您的主要使用场景涉及读取和更新数据原子("资源"),则REST提供了一种更轻量,可发现且直接的数据访问方法.此外,使用REST构建真正瘦客户端(移动设备,JavaScript,甚至shell脚本)通常更容易.
例如:如果您的数据模型完全是关于客户的,而您的主要操作涉及阅读客户并回写更改,那么REST就可以了.使用GET/POST/PUT/DELETE HTTP协议是使协议易于发现且易于使用的绝佳方法,即使对于不熟悉您的应用程序的人也是如此.
然而,这将我们带到第二点.
如果您需要提供具有查询功能的Web API,该怎么办?例如,一个典型的场景可能是"让我获得5个最新客户".在这种情况下,纯REST几乎不提供API可发现性.输入OData(www.odata.org),然后再次滚动; 从这个观点来看,基于OData URI的查询语法在REST服务的正常极其简单的基于ID的寻址之上增加了一些众所周知的抽象.
但是,有些方面在REST方面可能难以表现.第三点:如果您无法合理地对其进行建模,请考虑使用SOA.
例如,如果常见的使用场景涉及在工作流阶段(例如,"新客户","收到信用请求","信用批准")之间转换客户,则使用REST对这些阶段进行建模可能会很复杂.是否应将不同阶段表示为实体中的属性值?或许,是否应将不同阶段建模为客户所在的容器?如果它是一个属性,你是否总是想在更新它时做一个完整的PUT?您是否应该使用自定义HTTP动词("APPROVE http:// mysite/customers/contoso HTTP/1.0")?
这些是没有普遍答案的有效问题.所有东西都可以在REST中建模,但是在某些时候,抽象分解了很多,以至于很多REST的面向人类的好处(可发现性,易于理解)都会丢失.当然,技术优势(如所有HTTP级别的优点)仍然可以获得,但在大多数情况下,它们并不是真正的关键参数.
第四,也是最后,SOA模型简单地做了很多事情.也许最重要的是交易.虽然它在WS-*世界中也是一个相当复杂的通用问题,但很少需要通用事务,并且通常可以用相当简单的原子操作替换.
例如,考虑一种情况,您希望创建一个允许在一个帐户下合并两个客户及其所有购买的操作.当然,所有这些都需要发生或不发生; 典型的交易场景.在REST中对此进行建模需要付出巨大的努力.对于像这样的特殊场景,简单的SOA方法是创建一个在内部实现事务的操作(MergeCustomers).
对于更高级的场景,WS-*堆栈提供了REST世界中不易获得的工具(包括WS-Transaction,WS-Security等等).虽然大多数API都不需要这些(或者更好地以更简单的方式实现它们),但我认为重写所有这些只是为了100%REST是不值得的.
展望两全其美.对于绝大多数场景,在REST中使用基本CRUD并在SOA中提供一些专门操作是完全可以接受的.
此外,这些API可以设计为一起行动.例如,基于SOA的MergeCustomers操作应该返回什么?它可能会返回合并客户的序列化副本,但在大多数情况下,我会选择返回作为新合并客户的REST资源的URI.这样,即使SOA对于特定方案是必需的,您也总是只有一个客户表示.
以前的方法的缺点是需要客户端支持REST和SOA.然而,这很少是一个真正的问题(除了纯粹的架构观点).最简单的客户端通常具有REST功能,具有HTTP堆栈的定义,并且它们很少运行更复杂的操作.
当然,您的里程可能会有所不同.您的应用程序(及其客户端),本地策略和向后兼容性要求的需求通常似乎在正手中主导这些讨论,因此REST与SOA的讨论很少是纯粹的技术优点.
| 归档时间: |
|
| 查看次数: |
697 次 |
| 最近记录: |