CRUD不适合REST吗?

Arnon Rotem-Gal-Oz在他的新博文"CRUD不适合REST"中这样开篇:

表面上看起来它们很相配(无论从技术上还是架构上),然而,一旦深入了解,你就会发现它们并不相配。

今天,REST架构风格的常见实现是基于HTTP协议及其相应动作(如POST,GET, PUT和DELET)的。而且,这些动作经常会被实现者映射为CRUD术语——Create,Read,Update和Delete。典型的做法是1对1映射。

  • GET通常被映射为CRUD中的Read,只是GET还提供了超越开箱即用(Out-of-the-box)的SELECT(即Read)映射的一些特征。
  • DELETE通常被映射为CRUD中的Delete
  • PUT通常映射为CRUD中的Update,只不过增加了一些限制:
    • PUT替换的对象是整个资源,而Update可以替换一部分。
    • PUT可以用于创建一个资源(当客户端设定RUI时)
  • POST通常被映射为CRUD中的Create,但它仅支持创建子资源,可是POST支持对资源的部分更新。

Arnon认为:

HTTP动作更加面向文档而不是数据库,至少在谈到HTTP动作时,执行Update,Delete和Create新资源采用的做法和CRUD在数据库的世界里的做法是不完全一样的。

然而,CRUD不适合于REST的最大原因是架构上的,REST的核心是使用超媒体实现的协议状态机。Arnon引用Tim Ewald的话:

……这是我所理解的。每一种交互协议都有一个状态机,有些很简单,有些则比较复杂。当你通过RPC来实现协议时,你是在创建用于修改交互状态的方法。从交互端点看来,状态是由一个黑盒子维护的。由于协议状态是隐藏的,所以很容易出错。比如,你很有可能在初始化之前就调用某个流程。很长一段时间里,人们一直通过为接口的类型信息下注解的方式来寻找避免这类问题出现的方法,但是我从没有看到任何主流的解决方法。事实上,协议的状态隐藏在方法调用的背后,在方法调用的过程中隐式地修改状态,这个事实更增了版本控制的趣味。

REST的精髓是通过URI来显式描述协议的状态。协议状态机的当前状态是由最近一次操作的URI以及该操作获取到的状态描述决定的。若要修改状态,那么就对URI进行相应的目标状态的操作,使资源呈现期待的新状态。状态描述包括指向其他状态的链接(状态图中的弧线),通过这些链接可以从当前状态移动到目标状态。基于浏览器的应用就是这么工作的,而且你的应用程序协议没有理由不能那样工作。(ATOM发布协议是一个经典的状态机例子,尽管它被经常认为是关于实体的,而不是状态机的)

接着John Evdemon&rsquo的文章中所阐述的为什么CRUD服务是SOA的反模式,Arnon描述了CRUD REST的缺点:

  • 限制了服务的整体概念——没有业务逻辑。
  • 暴露了内部的数据库结构,或者数据接口,而不是仔细考虑后的接口。
  • 鼓励直通服务和数据的做法。
  • 建立的是块(Blob)服务(数据源)
  • 鼓励细小的多重服务(为块服务定义多重接口),而忽略了分布式计算的若干谬误。
  • 仅仅是“批着羊皮”的C-S结构。

Arnon在博文结尾的时候再次强调,仅仅采用诸如HTTP,XML,JASON等标准(尽管他们很有用)还不能构成 REST,而只有采用了REST架构才算真正的REST。

这篇博文的重要性在于它提醒到:REST和SOA类似,它不是一组标准和流行的API,而是一种架构模型,这才是需要去理解和遵循的。

查看英文原文:Is CRUD Bad for REST?

你可能感兴趣的:(CRUD不适合REST吗?)