#18.REST架构风格
从毕业设计误打误撞选了《RESTful架构webservice应用研究》这个课题,到现在也三年有多了。但直至目前,个人对REST的理解都还欠缺火候。随着知识的积累与深入,对同一个事务的认知都在变化。且让我把当前的想法记录下来,秋后才有账可算。:)
##18.1 什么是REST
REST,英文名叫__Representational State Transfer__,翻译为中文为__表述性状态转移__。okay,我们不要纠结与名词的含义,简而言之:REST就是利用__用户友好的URL风格__、利用现存的__HTTP动词__以及__HTTP相关的特性__来规范WebService接口。实际上它是一种交互数据的协议规范。
在REST之前,我们常用SOAP(简单对象访问协议)来作为数据交换的协议,几乎绝大部分的开发平台都支持SOAP,使用SOAP就可以实现跨平台进行数据的处理(当然,开发人员可以不使用SOAP而自行设计数据通信协议,但是这样做不利于跨平台、拓展以及让后期开发人员理解和使用,还要写一大推的API文档,GOD,当然,小型项目随你怎么搞,呵呵了)。但是,在某些场合使用SOAP确实是点杀鸡焉用牛刀的赶脚。于是乎,有个美国的小胖子就利用HTTP协议发明了REST。接着Web大行其道的东风,REST很顺利得走上了历史舞台。
当然,我并不认为REST是一种架构,我更认同它是一种__设计风格或理念__。当大家都遵循这样的设计理念后,那么拓展、跨平台、维护也就水到渠成了(API文档都不用写了,呵呵)。
##18.2 REST特性
REST是建立在HTTP之上的,所以REST的很多特征都与HTTP息息相关。
- 面向资源(Resource Oriented)
- 可寻址(Addressability)
- 连通性(Connectedness)
- 无状态(Statelessness)
- 统一接口(Uniform Interface)
- 超文本驱动(Hypertext Driven)
###18.2.1 面向资源(Resource Oriented)
面向资源是REST最明显的特征,每个URI都唯一指向一个资源,同时一个资源可以由多个URI表示。
例如http://www.exmaple.com/book/1
指向了ID为1的book,我们也可以使用http://www.xxx.com/book/1
指向该资源。于此同时,我们可以根据这种URI风格进行拓展,例如我们可以用http://www.example.com/book/1/page/10086
来表示ID为1的书的10086页的资源。
仔细想想我们在没接触REST以前,我们的URI是怎么设计的,一般,我们都会使用动词加HTTP参数,例如:
http://www.example.com/getBook?id=1
http://www.example.com/queryBook?id=1
http://www.example.com/getBookById?id=2
http://www.example.com/getPageOfBook?bookId=1&page=10086
http://www.example.com/getPage?bookId=1&page=10086
http://www.example.com/queryPage?bookId=2&pageNo=10086
往下的我就不写了,每个开发人员都有自己的喜好和习惯,使用的动词、参数名称、URL路径都不尽想用,很难想象在一个Web系统中,各类风格不同URL混杂在一起,无论对开发、维护还是调用者,都是异常噩梦。相信很多架构师在之前都有被URI设计挠破头皮的经历。
相对于这些URI风格,REST风格的URI的优势不言而喻:
- 容易理解
- 易于拓展
###18.2.2 可寻址(Addressability)
每一个资源都有一个唯一的URI标识。我们可以根据URI找到相应的资源。甚至,我们可以根据这些URI类比其他资源的地址。
例如http://www.ppurl.com/2014/
表示2014年新增的资源;那么我可以猜测http://www.ppurl.com/2014/03/
为2014年3月新增的资源;http://www.ppurl.com/2014/03/31/
为2014年3月31日新增的资源;
而实际上也正如我所想。(这是一个软件类的电子书网站,很强大,请笑纳: ))
###18.2.3 连通性(Connectedness)
REST指出,资源不应该是孤立的,应该使用超链接将资源关联起来。这个概念很有意思,而实际上会被很多开发人员忽略。后面我们再来详细展开讨论。
###18.2.4 无状态(Statelessness)
无状态性意味着每个HTTP请求都是彼此孤立,互不干扰的。REST的无状态性,让横向实现分布性系统提供了方便。URI在前面我们已经提过,这里来说一下HTTP方法。
###18.2.5 统一接口(Uniform Interface)
虽然浏览器只支持HTTP的GET和POST方法,我们也知道GET方法用来获取资源,而POST方法通常用来添加、修改和删除资源的。但是实际上HTTP为了我们提供了更有语义的方法。
HTTP方法 | 动作表示 | 示例 | 说明 |
---|---|---|---|
GET | 获取资源 | GET http://example.com/book/1 |
获取ID为1的书籍 |
POST | 添加资源 | POST http://example.com/book/1 |
添加书籍,该书籍ID为1 |
PUT | 修改资源 | PUT http://example.com/book/1 |
修改书籍,该书籍ID为1 |
DELETE | 删除资源 | DELETE http://example.com/book/1 |
删除书籍,该书籍ID为1 |
HTTP还提供了其他的HTTP方法,这里不再累赘,只叙述CRUD。
可以看到REST是使用现成的HTTP方法来更新资源的状态(这就是__状态转移__之意),增删改查分别对应POST、DELETE、PUT和GET方法。相比我们以前使用的动词,如_delBook_、deleteBook、removeBook、_book?operation=delete_等等。REST实在太高上大了。
####18.2.5.1 使用HTTP动词的优势 GET、POST、PUT、DELETE,幂等安全等特性。
客户端与服务器之间通过特定的URI和HTTP方法进行交互。
###18.2.6 超文本驱动(Hypertext Driven)
##18.3 URL设计(事实上的妥协)
##18.4 REST优势
##18.5 参考资料