最近几年RESTful的架构成为主流。但是,感觉每个人对RESTful的理解都有所不同。自己也看了不少文章,听了些讲座。RESTful是一种风格,不是一种标准,这给了大众自由把握的空间。我从自己的行业经验和对技术的理解,来写自己对RESTful的理解。
为什么这么讲呢?首先,RESTful的发明者Roy Fielding,他同时也是HTTP规范的制订者之一。在我看来,RESTful风格和HTTP有极其相似的理念。从理论上说,RESTful可以是非HTTP的,但实际运用上几乎都是HTTP的。我还没见过不在HTTP上的RESTful运用。我认为,Roy Fielding是把HTTP的理念单独抽出来形成RESTful风格。或者说,Roy Fielding认为大家在滥用HTTP协议的初衷,所以要强化原来的理念,单独剥离出来。
最典型的就是动词的使用:CRUD对应的PUT
,POST
,DELETE
和GET
。这些HTTP header里的标志本来就是设计的原意。很多场合,或许是为了图方便,一个应用全都使用一个GET或者POST。当然,程序不会错,但是当你用GET的header去做一个更新操作的时候,这肯定不是制订HTTP规范的人的意图。所以,从这个角度来讲,原先的SOAP是滥用了HTTP协议。
RESTful里还有cache的概念,想想HTTP协议里面有一大堆和cache相关的header。和时间相关的cache,还有和内容相关的cache的。这些cache必须和GET动词联合用才有效果。这完全就是HTTP的概念。当然,还有标准的response code。
这是RESTful最高的最成熟的级别,也是大家感觉比较玄虚的部分。别忘了我之前说的:RESTful和HTTP的关系。我认为,现在一般的网页都基本实现了这个HATEOAS!是不是觉得不太对?!看看HATEOAS的一个重要标准就是:client不需要事先知道server的变更,仍旧能正常工作。想想我们平时用浏览器上网,其实就能达到这个目的。譬如,一个网站改版了,用户仍旧能够完成先前的操作。这是个自解释的系统。
问题是在浏览网页这个例子里面,人也是系统的一部分,是人的大脑才识别出了页面的变化。作为一个计算机系统,这就很难做到了。现实中,似乎也没有系统做到HATEOAS。
说到RESTful,必然会谈及SOAP。我个人最大的体会是SOAP太难用,我觉得这都不用解释了。在java应用里,光用工具生成源代码这步,就让人受不了。而且这样做糟糕的是client端和server端在代码上就形成了耦合。
另外,由于SOAP是自己另起炉灶自己的一套规范,所以它只是把HTTP当作一个非常底层的通讯协议。把HTTP当作一个非常底层的通讯协议的坏处就是丧失了HTTP自带的强大的生态系统。譬如cache,很多软硬件都是天然支持HTTP的cache机制的。只要设置,带cache语意的HTTP通讯就可以得到很好的cache功能。但是,一旦使用SOAP这样全程POST类型的请求,就无法利用这些软硬件的cache功能。
在现实开发中,几乎很难把业务接口都归到resource上。有些操作真就不是CRUD这么纯粹。这个时候,给大家一个最佳实践,也是最贴近RESTful的一个标准。用幂等性(idempotence)和副作用来选择动词。 譬如,有一个操作每次触发都不会改变系统状态(无副作用),而且多次触发和单次触发对系统状态影响等价(幂等)。这个操作用GET就比较合理。如果一个操作有一个操作每次触发都会改变系统状态(有副作用),而且多次触发和单次触发对系统状态影响不等价(不幂等),这个操作用POST就比较合理。